17961SNatalie.Li@Sun.COM /*
27961SNatalie.Li@Sun.COM * CDDL HEADER START
37961SNatalie.Li@Sun.COM *
47961SNatalie.Li@Sun.COM * The contents of this file are subject to the terms of the
57961SNatalie.Li@Sun.COM * Common Development and Distribution License (the "License").
67961SNatalie.Li@Sun.COM * You may not use this file except in compliance with the License.
77961SNatalie.Li@Sun.COM *
87961SNatalie.Li@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97961SNatalie.Li@Sun.COM * or http://www.opensolaris.org/os/licensing.
107961SNatalie.Li@Sun.COM * See the License for the specific language governing permissions
117961SNatalie.Li@Sun.COM * and limitations under the License.
127961SNatalie.Li@Sun.COM *
137961SNatalie.Li@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147961SNatalie.Li@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157961SNatalie.Li@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167961SNatalie.Li@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177961SNatalie.Li@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187961SNatalie.Li@Sun.COM *
197961SNatalie.Li@Sun.COM * CDDL HEADER END
207961SNatalie.Li@Sun.COM */
21*12508Samw@Sun.COM
227961SNatalie.Li@Sun.COM /*
23*12508Samw@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
247961SNatalie.Li@Sun.COM */
257961SNatalie.Li@Sun.COM
267961SNatalie.Li@Sun.COM /*
277961SNatalie.Li@Sun.COM * Service Control Services (SVCCTL) RPC interface definition.
287961SNatalie.Li@Sun.COM * This interface provides remote access to list SMF services
297961SNatalie.Li@Sun.COM * from a Windows client.
307961SNatalie.Li@Sun.COM *
317961SNatalie.Li@Sun.COM * SVCCTL access is restricted to administrators: members of the
327961SNatalie.Li@Sun.COM * Domain Admins or Administrators groups.
337961SNatalie.Li@Sun.COM */
348334SJose.Borrego@Sun.COM
357961SNatalie.Li@Sun.COM #include <stdio.h>
367961SNatalie.Li@Sun.COM #include <strings.h>
37*12508Samw@Sun.COM
38*12508Samw@Sun.COM #include <smbsrv/libsmb.h>
39*12508Samw@Sun.COM #include <smbsrv/libmlsvc.h>
407961SNatalie.Li@Sun.COM #include <smbsrv/nmpipes.h>
4110001SJoyce.McIntosh@Sun.COM #include <smbsrv/ntifs.h>
4210122SJordan.Brown@Sun.COM #include <smbsrv/winsvc.h>
4310122SJordan.Brown@Sun.COM #include <smbsrv/ndl/svcctl.ndl>
4410122SJordan.Brown@Sun.COM #include <smbsrv/libmlsvc.h>
457961SNatalie.Li@Sun.COM
4610001SJoyce.McIntosh@Sun.COM #define SVCCTL_SECURITY_BUFSIZE 256
4710001SJoyce.McIntosh@Sun.COM #define SVCCTL_ENUMSERVICES_MINBUFSIZE 1024
4810001SJoyce.McIntosh@Sun.COM
497961SNatalie.Li@Sun.COM #define SVCCTL_OPENSVC_OP_UNIMPLEMENTED(S) \
507961SNatalie.Li@Sun.COM ((S) & SERVICE_CHANGE_CONFIG) || \
517961SNatalie.Li@Sun.COM ((S) & SERVICE_PAUSE_CONTINUE) || \
527961SNatalie.Li@Sun.COM ((S) & SERVICE_START) || \
537961SNatalie.Li@Sun.COM ((S) & SERVICE_STOP) || \
547961SNatalie.Li@Sun.COM ((S) & SERVICE_ENUMERATE_DEPENDENTS)
557961SNatalie.Li@Sun.COM
5610504SKeyur.Desai@Sun.COM typedef union {
5710504SKeyur.Desai@Sun.COM uint8_t *svc_buf;
5810504SKeyur.Desai@Sun.COM svc_description_t *svc_desc;
5910504SKeyur.Desai@Sun.COM svc_failure_actions_t *svc_fac;
6010504SKeyur.Desai@Sun.COM svc_delayed_auto_start_t *svc_dstart;
6110504SKeyur.Desai@Sun.COM svc_config_failure_action_t *svc_cfa;
6210504SKeyur.Desai@Sun.COM } svc_config_rsp_t;
6310504SKeyur.Desai@Sun.COM
648334SJose.Borrego@Sun.COM static int svcctl_s_Close(void *, ndr_xa_t *);
6510001SJoyce.McIntosh@Sun.COM static int svcctl_s_ControlService(void *, ndr_xa_t *);
6610001SJoyce.McIntosh@Sun.COM static int svcctl_s_DeleteService(void *, ndr_xa_t *);
6710001SJoyce.McIntosh@Sun.COM static int svcctl_s_QueryServiceSecurity(void *, ndr_xa_t *);
6810001SJoyce.McIntosh@Sun.COM static int svcctl_s_SetServiceSecurity(void *, ndr_xa_t *);
698334SJose.Borrego@Sun.COM static int svcctl_s_OpenManager(void *, ndr_xa_t *);
708334SJose.Borrego@Sun.COM static int svcctl_s_OpenService(void *, ndr_xa_t *);
718334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceStatus(void *, ndr_xa_t *);
728334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceConfig(void *, ndr_xa_t *);
7310001SJoyce.McIntosh@Sun.COM static int svcctl_s_StartService(void *, ndr_xa_t *);
7410001SJoyce.McIntosh@Sun.COM static int svcctl_s_EnumDependentServices(void *, ndr_xa_t *);
758334SJose.Borrego@Sun.COM static int svcctl_s_EnumServicesStatus(void *, ndr_xa_t *);
768334SJose.Borrego@Sun.COM static int svcctl_s_GetServiceDisplayNameW(void *, ndr_xa_t *);
778334SJose.Borrego@Sun.COM static int svcctl_s_GetServiceKeyNameW(void *, ndr_xa_t *);
7810001SJoyce.McIntosh@Sun.COM static int svcctl_s_OpenSCManagerA(void *, ndr_xa_t *);
7910001SJoyce.McIntosh@Sun.COM static int svcctl_s_OpenServiceA(void *, ndr_xa_t *);
8010001SJoyce.McIntosh@Sun.COM static int svcctl_s_EnumServicesStatusA(void *, ndr_xa_t *);
818334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceConfig2W(void *, ndr_xa_t *);
8210001SJoyce.McIntosh@Sun.COM static int svcctl_s_QueryServiceStatusEx(void *, ndr_xa_t *);
837961SNatalie.Li@Sun.COM
848334SJose.Borrego@Sun.COM static ndr_stub_table_t svcctl_stub_table[] = {
857961SNatalie.Li@Sun.COM { svcctl_s_Close, SVCCTL_OPNUM_Close },
8610001SJoyce.McIntosh@Sun.COM { svcctl_s_ControlService, SVCCTL_OPNUM_ControlService },
8710001SJoyce.McIntosh@Sun.COM { svcctl_s_DeleteService, SVCCTL_OPNUM_DeleteService },
8810001SJoyce.McIntosh@Sun.COM { svcctl_s_QueryServiceSecurity, SVCCTL_OPNUM_QueryServiceSecurity },
8910001SJoyce.McIntosh@Sun.COM { svcctl_s_SetServiceSecurity, SVCCTL_OPNUM_SetServiceSecurity },
907961SNatalie.Li@Sun.COM { svcctl_s_OpenManager, SVCCTL_OPNUM_OpenManager },
917961SNatalie.Li@Sun.COM { svcctl_s_OpenService, SVCCTL_OPNUM_OpenService },
927961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceStatus, SVCCTL_OPNUM_QueryServiceStatus },
937961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceConfig, SVCCTL_OPNUM_QueryServiceConfig },
9410001SJoyce.McIntosh@Sun.COM { svcctl_s_StartService, SVCCTL_OPNUM_StartService },
9510001SJoyce.McIntosh@Sun.COM { svcctl_s_EnumDependentServices,
9610001SJoyce.McIntosh@Sun.COM SVCCTL_OPNUM_EnumDependentServices },
977961SNatalie.Li@Sun.COM { svcctl_s_EnumServicesStatus, SVCCTL_OPNUM_EnumServicesStatus },
987961SNatalie.Li@Sun.COM { svcctl_s_GetServiceDisplayNameW,
997961SNatalie.Li@Sun.COM SVCCTL_OPNUM_GetServiceDisplayNameW },
1007961SNatalie.Li@Sun.COM { svcctl_s_GetServiceKeyNameW, SVCCTL_OPNUM_GetServiceKeyNameW },
10110001SJoyce.McIntosh@Sun.COM { svcctl_s_OpenSCManagerA, SVCCTL_OPNUM_OpenSCManagerA },
10210001SJoyce.McIntosh@Sun.COM { svcctl_s_OpenServiceA, SVCCTL_OPNUM_OpenServiceA },
10310001SJoyce.McIntosh@Sun.COM { svcctl_s_EnumServicesStatusA, SVCCTL_OPNUM_EnumServicesStatusA },
1047961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceConfig2W, SVCCTL_OPNUM_QueryServiceConfig2W },
10510001SJoyce.McIntosh@Sun.COM { svcctl_s_QueryServiceStatusEx, SVCCTL_OPNUM_QueryServiceStatusEx },
1067961SNatalie.Li@Sun.COM {0}
1077961SNatalie.Li@Sun.COM };
1087961SNatalie.Li@Sun.COM
1098334SJose.Borrego@Sun.COM static ndr_service_t svcctl_service = {
1107961SNatalie.Li@Sun.COM "SVCCTL", /* name */
1117961SNatalie.Li@Sun.COM "Service Control Services", /* desc */
1127961SNatalie.Li@Sun.COM "\\svcctl", /* endpoint */
1137961SNatalie.Li@Sun.COM PIPE_NTSVCS, /* sec_addr_port */
1148334SJose.Borrego@Sun.COM "367abb81-9844-35f1-ad32-98f038001003", 2, /* abstract */
1158334SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
1167961SNatalie.Li@Sun.COM 0, /* no bind_instance_size */
1177961SNatalie.Li@Sun.COM 0, /* no bind_req() */
1187961SNatalie.Li@Sun.COM 0, /* no unbind_and_close() */
1197961SNatalie.Li@Sun.COM 0, /* use generic_call_stub() */
1207961SNatalie.Li@Sun.COM &TYPEINFO(svcctl_interface), /* interface ti */
1217961SNatalie.Li@Sun.COM svcctl_stub_table /* stub_table */
1227961SNatalie.Li@Sun.COM };
1237961SNatalie.Li@Sun.COM
1247961SNatalie.Li@Sun.COM /*
1257961SNatalie.Li@Sun.COM * svcctl_initialize
1267961SNatalie.Li@Sun.COM *
1277961SNatalie.Li@Sun.COM * This function registers the SVCCTL RPC interface with the RPC runtime
1287961SNatalie.Li@Sun.COM * library. It must be called in order to use either the client side
1297961SNatalie.Li@Sun.COM * or the server side functions.
1307961SNatalie.Li@Sun.COM */
1317961SNatalie.Li@Sun.COM void
svcctl_initialize(void)1327961SNatalie.Li@Sun.COM svcctl_initialize(void)
1337961SNatalie.Li@Sun.COM {
1348334SJose.Borrego@Sun.COM (void) ndr_svc_register(&svcctl_service);
13510122SJordan.Brown@Sun.COM svcctl_init();
13610122SJordan.Brown@Sun.COM }
13710122SJordan.Brown@Sun.COM
13810122SJordan.Brown@Sun.COM void
svcctl_finalize(void)13910122SJordan.Brown@Sun.COM svcctl_finalize(void)
14010122SJordan.Brown@Sun.COM {
14110122SJordan.Brown@Sun.COM svcctl_fini();
1427961SNatalie.Li@Sun.COM }
1437961SNatalie.Li@Sun.COM
1447961SNatalie.Li@Sun.COM /*
1457961SNatalie.Li@Sun.COM * svcctl_hdlookup
1467961SNatalie.Li@Sun.COM *
1477961SNatalie.Li@Sun.COM * Handle lookup wrapper to validate the local service and/or manager context.
1487961SNatalie.Li@Sun.COM */
1497961SNatalie.Li@Sun.COM static ndr_handle_t *
svcctl_hdlookup(ndr_xa_t * mxa,ndr_hdid_t * id,svcctl_context_type_t type)1507961SNatalie.Li@Sun.COM svcctl_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, svcctl_context_type_t type)
1517961SNatalie.Li@Sun.COM {
1527961SNatalie.Li@Sun.COM ndr_handle_t *hd;
1537961SNatalie.Li@Sun.COM svcctl_context_t *ctx;
1547961SNatalie.Li@Sun.COM
1557961SNatalie.Li@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL)
1567961SNatalie.Li@Sun.COM return (NULL);
1577961SNatalie.Li@Sun.COM
1587961SNatalie.Li@Sun.COM if ((ctx = (svcctl_context_t *)hd->nh_data) == NULL)
1597961SNatalie.Li@Sun.COM return (NULL);
1607961SNatalie.Li@Sun.COM
1617961SNatalie.Li@Sun.COM if ((ctx->c_type != type) || (ctx->c_ctx.uc_cp == NULL))
1627961SNatalie.Li@Sun.COM return (NULL);
1637961SNatalie.Li@Sun.COM
1647961SNatalie.Li@Sun.COM return (hd);
1657961SNatalie.Li@Sun.COM }
1667961SNatalie.Li@Sun.COM
1677961SNatalie.Li@Sun.COM /*
1687961SNatalie.Li@Sun.COM * svcctl_hdfree
1697961SNatalie.Li@Sun.COM *
1707961SNatalie.Li@Sun.COM * Handle deallocation wrapper to free the local service and/or manager context.
1717961SNatalie.Li@Sun.COM */
1727961SNatalie.Li@Sun.COM static void
svcctl_hdfree(ndr_xa_t * mxa,ndr_hdid_t * id)1737961SNatalie.Li@Sun.COM svcctl_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id)
1747961SNatalie.Li@Sun.COM {
1757961SNatalie.Li@Sun.COM ndr_handle_t *hd;
1767961SNatalie.Li@Sun.COM svcctl_context_t *ctx;
1777961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
1787961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx;
1797961SNatalie.Li@Sun.COM
1807961SNatalie.Li@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
1817961SNatalie.Li@Sun.COM ctx = (svcctl_context_t *)hd->nh_data;
1827961SNatalie.Li@Sun.COM
1837961SNatalie.Li@Sun.COM switch (ctx->c_type) {
1847961SNatalie.Li@Sun.COM case SVCCTL_MANAGER_CONTEXT:
1857961SNatalie.Li@Sun.COM mgr_ctx = ctx->c_ctx.uc_mgr;
1867961SNatalie.Li@Sun.COM svcctl_scm_fini(mgr_ctx);
1877961SNatalie.Li@Sun.COM svcctl_scm_scf_handle_fini(mgr_ctx);
1887961SNatalie.Li@Sun.COM free(mgr_ctx);
1897961SNatalie.Li@Sun.COM break;
1907961SNatalie.Li@Sun.COM
1917961SNatalie.Li@Sun.COM case SVCCTL_SERVICE_CONTEXT:
1927961SNatalie.Li@Sun.COM svc_ctx = ctx->c_ctx.uc_svc;
1937961SNatalie.Li@Sun.COM free(svc_ctx->sc_mgrid);
1947961SNatalie.Li@Sun.COM free(svc_ctx->sc_svcname);
1957961SNatalie.Li@Sun.COM free(svc_ctx);
1967961SNatalie.Li@Sun.COM break;
1977961SNatalie.Li@Sun.COM
1987961SNatalie.Li@Sun.COM default:
1997961SNatalie.Li@Sun.COM break;
2007961SNatalie.Li@Sun.COM }
2017961SNatalie.Li@Sun.COM
2027961SNatalie.Li@Sun.COM free(ctx);
2037961SNatalie.Li@Sun.COM ndr_hdfree(mxa, id);
2047961SNatalie.Li@Sun.COM }
2057961SNatalie.Li@Sun.COM }
2067961SNatalie.Li@Sun.COM
2077961SNatalie.Li@Sun.COM /*
2087961SNatalie.Li@Sun.COM * svcctl_mgr_hdalloc
2097961SNatalie.Li@Sun.COM *
2107961SNatalie.Li@Sun.COM * Handle allocation wrapper to setup the local manager context.
2117961SNatalie.Li@Sun.COM */
2127961SNatalie.Li@Sun.COM static ndr_hdid_t *
svcctl_mgr_hdalloc(ndr_xa_t * mxa)2137961SNatalie.Li@Sun.COM svcctl_mgr_hdalloc(ndr_xa_t *mxa)
2147961SNatalie.Li@Sun.COM {
2157961SNatalie.Li@Sun.COM svcctl_context_t *ctx;
2167961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
2177961SNatalie.Li@Sun.COM
2187961SNatalie.Li@Sun.COM if ((ctx = malloc(sizeof (svcctl_context_t))) == NULL)
2197961SNatalie.Li@Sun.COM return (NULL);
2207961SNatalie.Li@Sun.COM ctx->c_type = SVCCTL_MANAGER_CONTEXT;
2217961SNatalie.Li@Sun.COM
2227961SNatalie.Li@Sun.COM if ((mgr_ctx = malloc(sizeof (svcctl_manager_context_t))) == NULL) {
2237961SNatalie.Li@Sun.COM free(ctx);
2247961SNatalie.Li@Sun.COM return (NULL);
2257961SNatalie.Li@Sun.COM }
2267961SNatalie.Li@Sun.COM bzero(mgr_ctx, sizeof (svcctl_manager_context_t));
2277961SNatalie.Li@Sun.COM
2287961SNatalie.Li@Sun.COM if (svcctl_scm_scf_handle_init(mgr_ctx) < 0) {
2297961SNatalie.Li@Sun.COM free(mgr_ctx);
2307961SNatalie.Li@Sun.COM free(ctx);
2317961SNatalie.Li@Sun.COM return (NULL);
2327961SNatalie.Li@Sun.COM }
2337961SNatalie.Li@Sun.COM
2347961SNatalie.Li@Sun.COM if (svcctl_scm_init(mgr_ctx) < 0) {
2357961SNatalie.Li@Sun.COM svcctl_scm_scf_handle_fini(mgr_ctx);
2367961SNatalie.Li@Sun.COM free(mgr_ctx);
2377961SNatalie.Li@Sun.COM free(ctx);
2387961SNatalie.Li@Sun.COM return (NULL);
2397961SNatalie.Li@Sun.COM }
2407961SNatalie.Li@Sun.COM
2417961SNatalie.Li@Sun.COM ctx->c_ctx.uc_mgr = mgr_ctx;
2427961SNatalie.Li@Sun.COM
2437961SNatalie.Li@Sun.COM return (ndr_hdalloc(mxa, ctx));
2447961SNatalie.Li@Sun.COM }
2457961SNatalie.Li@Sun.COM
2467961SNatalie.Li@Sun.COM /*
2477961SNatalie.Li@Sun.COM * svcctl_get_mgr_ctx
2487961SNatalie.Li@Sun.COM *
2497961SNatalie.Li@Sun.COM * This function looks up a reference to local manager context.
2507961SNatalie.Li@Sun.COM */
2517961SNatalie.Li@Sun.COM static svcctl_manager_context_t *
svcctl_get_mgr_ctx(ndr_xa_t * mxa,ndr_hdid_t * mgr_id)2527961SNatalie.Li@Sun.COM svcctl_get_mgr_ctx(ndr_xa_t *mxa, ndr_hdid_t *mgr_id)
2537961SNatalie.Li@Sun.COM {
2547961SNatalie.Li@Sun.COM ndr_handle_t *hd;
2557961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
2567961SNatalie.Li@Sun.COM
2577961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, mgr_id, SVCCTL_MANAGER_CONTEXT);
2587961SNatalie.Li@Sun.COM if (hd == NULL)
2597961SNatalie.Li@Sun.COM return (NULL);
2607961SNatalie.Li@Sun.COM
2617961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr;
2627961SNatalie.Li@Sun.COM
2637961SNatalie.Li@Sun.COM return (mgr_ctx);
2647961SNatalie.Li@Sun.COM }
2657961SNatalie.Li@Sun.COM
2667961SNatalie.Li@Sun.COM /*
2677961SNatalie.Li@Sun.COM * svcctl_svc_hdalloc
2687961SNatalie.Li@Sun.COM *
2697961SNatalie.Li@Sun.COM * Handle allocation wrapper to setup the local service context.
2707961SNatalie.Li@Sun.COM */
2717961SNatalie.Li@Sun.COM static ndr_hdid_t *
svcctl_svc_hdalloc(ndr_xa_t * mxa,ndr_hdid_t * mgr_id,char * svc_name)2727961SNatalie.Li@Sun.COM svcctl_svc_hdalloc(ndr_xa_t *mxa, ndr_hdid_t *mgr_id, char *svc_name)
2737961SNatalie.Li@Sun.COM {
2747961SNatalie.Li@Sun.COM svcctl_context_t *ctx;
2757961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx;
2767961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
2777961SNatalie.Li@Sun.COM int max_name_sz = 0;
2787961SNatalie.Li@Sun.COM char *svcname;
2797961SNatalie.Li@Sun.COM
2807961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, mgr_id);
2817961SNatalie.Li@Sun.COM if (mgr_ctx == NULL)
2827961SNatalie.Li@Sun.COM return (NULL);
2837961SNatalie.Li@Sun.COM max_name_sz = mgr_ctx->mc_scf_max_fmri_len;
2847961SNatalie.Li@Sun.COM
2857961SNatalie.Li@Sun.COM if ((ctx = malloc(sizeof (svcctl_context_t))) == NULL) {
2867961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id);
2877961SNatalie.Li@Sun.COM return (NULL);
2887961SNatalie.Li@Sun.COM }
2897961SNatalie.Li@Sun.COM ctx->c_type = SVCCTL_SERVICE_CONTEXT;
2907961SNatalie.Li@Sun.COM
2917961SNatalie.Li@Sun.COM if ((svc_ctx = malloc(sizeof (svcctl_service_context_t))) == NULL) {
2927961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id);
2937961SNatalie.Li@Sun.COM free(ctx);
2947961SNatalie.Li@Sun.COM return (NULL);
2957961SNatalie.Li@Sun.COM }
2967961SNatalie.Li@Sun.COM bzero(svc_ctx, sizeof (svcctl_service_context_t));
2977961SNatalie.Li@Sun.COM
2987961SNatalie.Li@Sun.COM svc_ctx->sc_mgrid = malloc(sizeof (ndr_hdid_t));
2997961SNatalie.Li@Sun.COM svcname = malloc(max_name_sz);
3007961SNatalie.Li@Sun.COM
3017961SNatalie.Li@Sun.COM if ((svc_ctx->sc_mgrid == NULL) || (svcname == NULL)) {
3027961SNatalie.Li@Sun.COM free(svc_ctx->sc_mgrid);
3037961SNatalie.Li@Sun.COM free(svc_ctx);
3047961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id);
3057961SNatalie.Li@Sun.COM free(ctx);
3067961SNatalie.Li@Sun.COM return (NULL);
3077961SNatalie.Li@Sun.COM }
3087961SNatalie.Li@Sun.COM
3097961SNatalie.Li@Sun.COM svc_ctx->sc_svcname = svcname;
3107961SNatalie.Li@Sun.COM
3117961SNatalie.Li@Sun.COM bcopy(mgr_id, svc_ctx->sc_mgrid, sizeof (ndr_hdid_t));
3127961SNatalie.Li@Sun.COM (void) strlcpy(svc_ctx->sc_svcname, svc_name, max_name_sz);
3137961SNatalie.Li@Sun.COM
3147961SNatalie.Li@Sun.COM ctx->c_ctx.uc_svc = svc_ctx;
3157961SNatalie.Li@Sun.COM
3167961SNatalie.Li@Sun.COM return (ndr_hdalloc(mxa, ctx));
3177961SNatalie.Li@Sun.COM }
3187961SNatalie.Li@Sun.COM
3197961SNatalie.Li@Sun.COM /*
3207961SNatalie.Li@Sun.COM * svcctl_s_Close
3217961SNatalie.Li@Sun.COM *
3227961SNatalie.Li@Sun.COM * This is a request to close the SVCCTL interface specified by the
3237961SNatalie.Li@Sun.COM * handle. Free the handle and zero out the result handle for the
3247961SNatalie.Li@Sun.COM * client.
3257961SNatalie.Li@Sun.COM *
3267961SNatalie.Li@Sun.COM * Returns:
3277961SNatalie.Li@Sun.COM * ERROR_SUCCESS
3287961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE
3297961SNatalie.Li@Sun.COM */
3307961SNatalie.Li@Sun.COM static int
svcctl_s_Close(void * arg,ndr_xa_t * mxa)3318334SJose.Borrego@Sun.COM svcctl_s_Close(void *arg, ndr_xa_t *mxa)
3327961SNatalie.Li@Sun.COM {
3337961SNatalie.Li@Sun.COM struct svcctl_Close *param = arg;
3347961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
3357961SNatalie.Li@Sun.COM
3367961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, id);
3377961SNatalie.Li@Sun.COM
3387961SNatalie.Li@Sun.COM bzero(¶m->result_handle, sizeof (svcctl_handle_t));
3397961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS;
3408334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
3417961SNatalie.Li@Sun.COM }
3427961SNatalie.Li@Sun.COM
3437961SNatalie.Li@Sun.COM /*
34410001SJoyce.McIntosh@Sun.COM * svcctl_s_ControlService
34510001SJoyce.McIntosh@Sun.COM */
34610001SJoyce.McIntosh@Sun.COM static int
svcctl_s_ControlService(void * arg,ndr_xa_t * mxa)34710001SJoyce.McIntosh@Sun.COM svcctl_s_ControlService(void *arg, ndr_xa_t *mxa)
34810001SJoyce.McIntosh@Sun.COM {
34910001SJoyce.McIntosh@Sun.COM struct svcctl_ControlService *param = arg;
35010001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
35110001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
35210001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx;
35310001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx;
35410001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc;
35510001SJoyce.McIntosh@Sun.COM
35610001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
35710001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
35810001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService));
35910001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE;
36010001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
36110001SJoyce.McIntosh@Sun.COM }
36210001SJoyce.McIntosh@Sun.COM
36310001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc;
36410001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid);
36510001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) {
36610001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService));
36710001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE;
36810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
36910001SJoyce.McIntosh@Sun.COM }
37010001SJoyce.McIntosh@Sun.COM
37110001SJoyce.McIntosh@Sun.COM switch (param->control) {
37210001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_STOP:
37310001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_PAUSE:
37410001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_CONTINUE:
37510001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_INTERROGATE:
37610001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_SHUTDOWN:
37710001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_PARAMCHANGE:
37810001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDADD:
37910001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDREMOVE:
38010001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDENABLE:
38110001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDDISABLE:
38210001SJoyce.McIntosh@Sun.COM break;
38310001SJoyce.McIntosh@Sun.COM default:
38410001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService));
38510001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_PARAMETER;
38610001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
38710001SJoyce.McIntosh@Sun.COM }
38810001SJoyce.McIntosh@Sun.COM
38910001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname);
39010001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) {
39110001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService));
39210001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST;
39310001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
39410001SJoyce.McIntosh@Sun.COM }
39510001SJoyce.McIntosh@Sun.COM
39610001SJoyce.McIntosh@Sun.COM param->service_status.service_type = SERVICE_WIN32_SHARE_PROCESS;
39710001SJoyce.McIntosh@Sun.COM param->service_status.cur_state = svcctl_scm_map_status(svc->sn_state);
39810001SJoyce.McIntosh@Sun.COM param->service_status.ctrl_accepted = 0;
39910001SJoyce.McIntosh@Sun.COM param->service_status.w32_exitcode = 0;
40010001SJoyce.McIntosh@Sun.COM param->service_status.svc_specified_exitcode = 0;
40110001SJoyce.McIntosh@Sun.COM param->service_status.check_point = 0;
40210001SJoyce.McIntosh@Sun.COM param->service_status.wait_hint = 0;
40310001SJoyce.McIntosh@Sun.COM
40410001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
40510001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
40610001SJoyce.McIntosh@Sun.COM }
40710001SJoyce.McIntosh@Sun.COM
40810001SJoyce.McIntosh@Sun.COM /*
40910001SJoyce.McIntosh@Sun.COM * svcctl_s_DeleteService
41010001SJoyce.McIntosh@Sun.COM */
41110001SJoyce.McIntosh@Sun.COM static int
svcctl_s_DeleteService(void * arg,ndr_xa_t * mxa)41210001SJoyce.McIntosh@Sun.COM svcctl_s_DeleteService(void *arg, ndr_xa_t *mxa)
41310001SJoyce.McIntosh@Sun.COM {
41410001SJoyce.McIntosh@Sun.COM struct svcctl_DeleteService *param = arg;
41510001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
41610001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
41710001SJoyce.McIntosh@Sun.COM
41810001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
41910001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
42010001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE;
42110001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
42210001SJoyce.McIntosh@Sun.COM }
42310001SJoyce.McIntosh@Sun.COM
42410001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
42510001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
42610001SJoyce.McIntosh@Sun.COM }
42710001SJoyce.McIntosh@Sun.COM
42810001SJoyce.McIntosh@Sun.COM /*
42910001SJoyce.McIntosh@Sun.COM * svcctl_s_QueryServiceSecurity
43010001SJoyce.McIntosh@Sun.COM */
43110001SJoyce.McIntosh@Sun.COM static int
svcctl_s_QueryServiceSecurity(void * arg,ndr_xa_t * mxa)43210001SJoyce.McIntosh@Sun.COM svcctl_s_QueryServiceSecurity(void *arg, ndr_xa_t *mxa)
43310001SJoyce.McIntosh@Sun.COM {
43410001SJoyce.McIntosh@Sun.COM struct svcctl_QueryServiceSecurity *param = arg;
43510001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
43610001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
43710001SJoyce.McIntosh@Sun.COM uint32_t sec_info;
43810001SJoyce.McIntosh@Sun.COM uint32_t bytes_needed = 0;
43910001SJoyce.McIntosh@Sun.COM uint32_t status;
44010001SJoyce.McIntosh@Sun.COM
44110001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
44210001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
44310001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
44410001SJoyce.McIntosh@Sun.COM goto query_service_security_error;
44510001SJoyce.McIntosh@Sun.COM }
44610001SJoyce.McIntosh@Sun.COM
44710001SJoyce.McIntosh@Sun.COM sec_info = param->security_info & SMB_ALL_SECINFO;
44810001SJoyce.McIntosh@Sun.COM if (sec_info == 0) {
44910001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER;
45010001SJoyce.McIntosh@Sun.COM goto query_service_security_error;
45110001SJoyce.McIntosh@Sun.COM }
45210001SJoyce.McIntosh@Sun.COM
45310001SJoyce.McIntosh@Sun.COM if (param->buf_size < SVCCTL_SECURITY_BUFSIZE) {
45410001SJoyce.McIntosh@Sun.COM bytes_needed = SVCCTL_SECURITY_BUFSIZE;
45510001SJoyce.McIntosh@Sun.COM status = ERROR_INSUFFICIENT_BUFFER;
45610001SJoyce.McIntosh@Sun.COM goto query_service_security_error;
45710001SJoyce.McIntosh@Sun.COM }
45810001SJoyce.McIntosh@Sun.COM
45910001SJoyce.McIntosh@Sun.COM param->buffer = NDR_MALLOC(mxa, SVCCTL_SECURITY_BUFSIZE);
46010001SJoyce.McIntosh@Sun.COM if (param->buffer == NULL) {
46110001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY;
46210001SJoyce.McIntosh@Sun.COM goto query_service_security_error;
46310001SJoyce.McIntosh@Sun.COM }
46410001SJoyce.McIntosh@Sun.COM
46510001SJoyce.McIntosh@Sun.COM bzero(param->buffer, sizeof (SVCCTL_SECURITY_BUFSIZE));
46610001SJoyce.McIntosh@Sun.COM param->buf_size = SVCCTL_SECURITY_BUFSIZE;
46710001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0;
46810001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
46910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
47010001SJoyce.McIntosh@Sun.COM
47110001SJoyce.McIntosh@Sun.COM query_service_security_error:
47210001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceSecurity));
47310001SJoyce.McIntosh@Sun.COM param->buf_size = 0;
47410001SJoyce.McIntosh@Sun.COM param->buffer = NDR_MALLOC(mxa, sizeof (uint32_t));
47510001SJoyce.McIntosh@Sun.COM param->bytes_needed = bytes_needed;
47610001SJoyce.McIntosh@Sun.COM param->status = status;
47710001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
47810001SJoyce.McIntosh@Sun.COM }
47910001SJoyce.McIntosh@Sun.COM
48010001SJoyce.McIntosh@Sun.COM
48110001SJoyce.McIntosh@Sun.COM /*
48210001SJoyce.McIntosh@Sun.COM * svcctl_s_SetServiceSecurity
48310001SJoyce.McIntosh@Sun.COM */
48410001SJoyce.McIntosh@Sun.COM static int
svcctl_s_SetServiceSecurity(void * arg,ndr_xa_t * mxa)48510001SJoyce.McIntosh@Sun.COM svcctl_s_SetServiceSecurity(void *arg, ndr_xa_t *mxa)
48610001SJoyce.McIntosh@Sun.COM {
48710001SJoyce.McIntosh@Sun.COM struct svcctl_SetServiceSecurity *param = arg;
48810001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
48910001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
49010001SJoyce.McIntosh@Sun.COM
49110001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
49210001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
49310001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE;
49410001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
49510001SJoyce.McIntosh@Sun.COM }
49610001SJoyce.McIntosh@Sun.COM
49710001SJoyce.McIntosh@Sun.COM if ((param->security_info & SMB_ALL_SECINFO) == 0) {
49810001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_PARAMETER;
49910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
50010001SJoyce.McIntosh@Sun.COM }
50110001SJoyce.McIntosh@Sun.COM
50210001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED;
50310001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
50410001SJoyce.McIntosh@Sun.COM }
50510001SJoyce.McIntosh@Sun.COM
50610001SJoyce.McIntosh@Sun.COM /*
5077961SNatalie.Li@Sun.COM * svcctl_s_OpenManager
5087961SNatalie.Li@Sun.COM *
5097961SNatalie.Li@Sun.COM * Request to open the service control manager.
5107961SNatalie.Li@Sun.COM * The caller must have administrator rights in order to open this
5117961SNatalie.Li@Sun.COM * interface. We don't support write (SC_MANAGER_LOCK) access.
5127961SNatalie.Li@Sun.COM *
5137961SNatalie.Li@Sun.COM * Returns:
5147961SNatalie.Li@Sun.COM * ERROR_SUCCESS
5157961SNatalie.Li@Sun.COM * ERROR_ACCESS_DENIED
5167961SNatalie.Li@Sun.COM *
5177961SNatalie.Li@Sun.COM * On success, returns a handle for use with subsequent svcctl requests.
5187961SNatalie.Li@Sun.COM */
5197961SNatalie.Li@Sun.COM static int
svcctl_s_OpenManager(void * arg,ndr_xa_t * mxa)5208334SJose.Borrego@Sun.COM svcctl_s_OpenManager(void *arg, ndr_xa_t *mxa)
5217961SNatalie.Li@Sun.COM {
5227961SNatalie.Li@Sun.COM struct svcctl_OpenManager *param = arg;
5237961SNatalie.Li@Sun.COM ndr_hdid_t *id = NULL;
5247961SNatalie.Li@Sun.COM int rc;
5257961SNatalie.Li@Sun.COM
5267961SNatalie.Li@Sun.COM rc = ndr_is_admin(mxa);
5277961SNatalie.Li@Sun.COM
5287961SNatalie.Li@Sun.COM if ((rc == 0) || (param->desired_access & SC_MANAGER_LOCK) != 0) {
5297961SNatalie.Li@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t));
5307961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED;
5318334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
5327961SNatalie.Li@Sun.COM }
5337961SNatalie.Li@Sun.COM
5347961SNatalie.Li@Sun.COM id = svcctl_mgr_hdalloc(mxa);
5357961SNatalie.Li@Sun.COM if (id) {
5367961SNatalie.Li@Sun.COM bcopy(id, ¶m->handle, sizeof (svcctl_handle_t));
5377961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS;
5387961SNatalie.Li@Sun.COM } else {
5397961SNatalie.Li@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t));
5407961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED;
5417961SNatalie.Li@Sun.COM }
5427961SNatalie.Li@Sun.COM
5438334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
5447961SNatalie.Li@Sun.COM }
5457961SNatalie.Li@Sun.COM
5467961SNatalie.Li@Sun.COM /*
5477961SNatalie.Li@Sun.COM * svcctl_s_OpenService
5487961SNatalie.Li@Sun.COM *
5497961SNatalie.Li@Sun.COM * Return a handle for use with subsequent svcctl requests.
5507961SNatalie.Li@Sun.COM *
5517961SNatalie.Li@Sun.COM * Returns:
5527961SNatalie.Li@Sun.COM * ERROR_SUCCESS
5537961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE
5547961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST
5557961SNatalie.Li@Sun.COM * ERROR_CALL_NOT_IMPLEMENTED
5567961SNatalie.Li@Sun.COM */
5577961SNatalie.Li@Sun.COM static int
svcctl_s_OpenService(void * arg,ndr_xa_t * mxa)5588334SJose.Borrego@Sun.COM svcctl_s_OpenService(void *arg, ndr_xa_t *mxa)
5597961SNatalie.Li@Sun.COM {
5607961SNatalie.Li@Sun.COM struct svcctl_OpenService *param = arg;
5617961SNatalie.Li@Sun.COM ndr_hdid_t *mgrid = (ndr_hdid_t *)¶m->manager_handle;
5627961SNatalie.Li@Sun.COM ndr_hdid_t *id = NULL;
5637961SNatalie.Li@Sun.COM ndr_handle_t *hd;
5647961SNatalie.Li@Sun.COM DWORD status;
5657961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
5667961SNatalie.Li@Sun.COM char *svc_name = (char *)param->service_name;
5677961SNatalie.Li@Sun.COM boolean_t unimplemented_operations = B_FALSE;
5687961SNatalie.Li@Sun.COM
5697961SNatalie.Li@Sun.COM /* Allow service handle allocations for only status & config queries */
5707961SNatalie.Li@Sun.COM unimplemented_operations =
5717961SNatalie.Li@Sun.COM SVCCTL_OPENSVC_OP_UNIMPLEMENTED(param->desired_access);
5727961SNatalie.Li@Sun.COM
5737961SNatalie.Li@Sun.COM if (unimplemented_operations) {
5747961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t));
5757961SNatalie.Li@Sun.COM param->status = ERROR_CALL_NOT_IMPLEMENTED;
5768334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
5777961SNatalie.Li@Sun.COM }
5787961SNatalie.Li@Sun.COM
5797961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, mgrid, SVCCTL_MANAGER_CONTEXT);
5807961SNatalie.Li@Sun.COM if (hd == NULL) {
5817961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t));
5827961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
5838334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
5847961SNatalie.Li@Sun.COM }
5857961SNatalie.Li@Sun.COM
5867961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr;
5877961SNatalie.Li@Sun.COM status = svcctl_scm_validate_service(mgr_ctx, svc_name);
5887961SNatalie.Li@Sun.COM if (status != ERROR_SUCCESS) {
5897961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t));
5907961SNatalie.Li@Sun.COM param->status = status;
5918334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
5927961SNatalie.Li@Sun.COM }
5937961SNatalie.Li@Sun.COM
5947961SNatalie.Li@Sun.COM id = svcctl_svc_hdalloc(mxa, mgrid, svc_name);
5957961SNatalie.Li@Sun.COM if (id) {
5967961SNatalie.Li@Sun.COM bcopy(id, ¶m->service_handle, sizeof (svcctl_handle_t));
5977961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS;
5987961SNatalie.Li@Sun.COM } else {
5997961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t));
6007961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED;
6017961SNatalie.Li@Sun.COM }
6027961SNatalie.Li@Sun.COM
6038334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6047961SNatalie.Li@Sun.COM }
6057961SNatalie.Li@Sun.COM
6067961SNatalie.Li@Sun.COM /*
6077961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceStatus
6087961SNatalie.Li@Sun.COM *
6097961SNatalie.Li@Sun.COM * Returns:
6107961SNatalie.Li@Sun.COM * ERROR_SUCCESS
6117961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE
6127961SNatalie.Li@Sun.COM */
6137961SNatalie.Li@Sun.COM static int
svcctl_s_QueryServiceStatus(void * arg,ndr_xa_t * mxa)6148334SJose.Borrego@Sun.COM svcctl_s_QueryServiceStatus(void *arg, ndr_xa_t *mxa)
6157961SNatalie.Li@Sun.COM {
6167961SNatalie.Li@Sun.COM struct svcctl_QueryServiceStatus *param = arg;
6177961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
6187961SNatalie.Li@Sun.COM ndr_handle_t *hd;
6197961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
6207961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx;
6217961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc;
6227961SNatalie.Li@Sun.COM
6237961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
6247961SNatalie.Li@Sun.COM if (hd == NULL) {
6257961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus));
6267961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
6278334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6287961SNatalie.Li@Sun.COM }
6297961SNatalie.Li@Sun.COM
6307961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc;
6317961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid);
6327961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) {
63310001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus));
6347961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
6358334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6367961SNatalie.Li@Sun.COM }
6377961SNatalie.Li@Sun.COM
6387961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname);
6397961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_state == NULL) {
64010001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus));
6417961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST;
6428334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6437961SNatalie.Li@Sun.COM }
6447961SNatalie.Li@Sun.COM
6457961SNatalie.Li@Sun.COM param->service_status.service_type = SERVICE_WIN32_SHARE_PROCESS;
6467961SNatalie.Li@Sun.COM param->service_status.cur_state = svcctl_scm_map_status(svc->sn_state);
6477961SNatalie.Li@Sun.COM param->service_status.ctrl_accepted = 0;
6487961SNatalie.Li@Sun.COM param->service_status.w32_exitcode = 0;
6497961SNatalie.Li@Sun.COM param->service_status.svc_specified_exitcode = 0;
6507961SNatalie.Li@Sun.COM param->service_status.check_point = 0;
6517961SNatalie.Li@Sun.COM param->service_status.wait_hint = 0;
6527961SNatalie.Li@Sun.COM
6537961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS;
6548334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
6557961SNatalie.Li@Sun.COM }
6567961SNatalie.Li@Sun.COM
6577961SNatalie.Li@Sun.COM /*
65810001SJoyce.McIntosh@Sun.COM * svcctl_s_EnumDependentServices
65910001SJoyce.McIntosh@Sun.COM *
66010001SJoyce.McIntosh@Sun.COM * Enumerate the list of services that depend on the specified service.
66110001SJoyce.McIntosh@Sun.COM */
66210001SJoyce.McIntosh@Sun.COM static int
svcctl_s_EnumDependentServices(void * arg,ndr_xa_t * mxa)66310001SJoyce.McIntosh@Sun.COM svcctl_s_EnumDependentServices(void *arg, ndr_xa_t *mxa)
66410001SJoyce.McIntosh@Sun.COM {
66510001SJoyce.McIntosh@Sun.COM struct svcctl_EnumDependentServices *param = arg;
66610001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
66710001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
66810001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx;
66910001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx;
67010001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc;
67110001SJoyce.McIntosh@Sun.COM int input_bufsize = 0;
67210001SJoyce.McIntosh@Sun.COM uint32_t status;
67310001SJoyce.McIntosh@Sun.COM
67410001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
67510001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
67610001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
67710001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error;
67810001SJoyce.McIntosh@Sun.COM }
67910001SJoyce.McIntosh@Sun.COM
68010001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc;
68110001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid);
68210001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) {
68310001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
68410001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error;
68510001SJoyce.McIntosh@Sun.COM }
68610001SJoyce.McIntosh@Sun.COM
68710001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname);
68810001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) {
68910001SJoyce.McIntosh@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST;
69010001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error;
69110001SJoyce.McIntosh@Sun.COM }
69210001SJoyce.McIntosh@Sun.COM
69310001SJoyce.McIntosh@Sun.COM switch (param->svc_state) {
69410001SJoyce.McIntosh@Sun.COM case SERVICE_STOPPED:
69510001SJoyce.McIntosh@Sun.COM case SERVICE_START_PENDING:
69610001SJoyce.McIntosh@Sun.COM case SERVICE_STOP_PENDING:
69710001SJoyce.McIntosh@Sun.COM case SERVICE_RUNNING:
69810001SJoyce.McIntosh@Sun.COM case SERVICE_CONTINUE_PENDING:
69910001SJoyce.McIntosh@Sun.COM case SERVICE_PAUSE_PENDING:
70010001SJoyce.McIntosh@Sun.COM case SERVICE_PAUSED:
70110001SJoyce.McIntosh@Sun.COM break;
70210001SJoyce.McIntosh@Sun.COM default:
70310001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER;
70410001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error;
70510001SJoyce.McIntosh@Sun.COM }
70610001SJoyce.McIntosh@Sun.COM
70710001SJoyce.McIntosh@Sun.COM if ((input_bufsize = param->buf_size) == 0) {
70810001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumDependentServices));
70910001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize;
71010001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, "");
71110001SJoyce.McIntosh@Sun.COM param->bytes_needed = 1024;
71210001SJoyce.McIntosh@Sun.COM param->svc_num = 0;
71310001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA;
71410001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
71510001SJoyce.McIntosh@Sun.COM }
71610001SJoyce.McIntosh@Sun.COM
71710001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, input_bufsize);
71810001SJoyce.McIntosh@Sun.COM if (param->services == NULL) {
71910001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY;
72010001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error;
72110001SJoyce.McIntosh@Sun.COM }
72210001SJoyce.McIntosh@Sun.COM
72310001SJoyce.McIntosh@Sun.COM bzero(param->services, input_bufsize);
72410001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize;
72510001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0;
72610001SJoyce.McIntosh@Sun.COM param->svc_num = 0;
72710001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
72810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
72910001SJoyce.McIntosh@Sun.COM
73010001SJoyce.McIntosh@Sun.COM enum_dependent_services_error:
73110001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumDependentServices));
73210001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, "");
73310001SJoyce.McIntosh@Sun.COM param->status = status;
73410001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
73510001SJoyce.McIntosh@Sun.COM }
73610001SJoyce.McIntosh@Sun.COM
73710001SJoyce.McIntosh@Sun.COM /*
7387961SNatalie.Li@Sun.COM * svcctl_s_EnumServicesStatus
7397961SNatalie.Li@Sun.COM *
74010001SJoyce.McIntosh@Sun.COM * Enumerate the list of services we support.
7417961SNatalie.Li@Sun.COM */
7427961SNatalie.Li@Sun.COM static int
svcctl_s_EnumServicesStatus(void * arg,ndr_xa_t * mxa)7438334SJose.Borrego@Sun.COM svcctl_s_EnumServicesStatus(void *arg, ndr_xa_t *mxa)
7447961SNatalie.Li@Sun.COM {
7457961SNatalie.Li@Sun.COM struct svcctl_EnumServicesStatus *param = arg;
7467961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle;
7477961SNatalie.Li@Sun.COM ndr_handle_t *hd;
7487961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
74910001SJoyce.McIntosh@Sun.COM uint32_t buf_size = 0;
75010001SJoyce.McIntosh@Sun.COM uint32_t svc_num;
75110001SJoyce.McIntosh@Sun.COM uint32_t resume_handle = 0;
75210001SJoyce.McIntosh@Sun.COM uint32_t status;
75310001SJoyce.McIntosh@Sun.COM
75410001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL)
75510001SJoyce.McIntosh@Sun.COM resume_handle = *param->resume_handle;
7567961SNatalie.Li@Sun.COM
7577961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT);
7587961SNatalie.Li@Sun.COM if (hd == NULL) {
75910001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
76010001SJoyce.McIntosh@Sun.COM goto enum_services_status_error;
7617961SNatalie.Li@Sun.COM }
7627961SNatalie.Li@Sun.COM
7637961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr;
7647961SNatalie.Li@Sun.COM if (svcctl_scm_refresh(mgr_ctx) != 0) {
76510001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
76610001SJoyce.McIntosh@Sun.COM goto enum_services_status_error;
7677961SNatalie.Li@Sun.COM }
7687961SNatalie.Li@Sun.COM
76910001SJoyce.McIntosh@Sun.COM buf_size = param->buf_size;
77010001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, buf_size);
7717961SNatalie.Li@Sun.COM if (param->services == NULL) {
77210001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY;
77310001SJoyce.McIntosh@Sun.COM goto enum_services_status_error;
7747961SNatalie.Li@Sun.COM }
77510001SJoyce.McIntosh@Sun.COM bzero(param->services, buf_size);
7767961SNatalie.Li@Sun.COM
77710001SJoyce.McIntosh@Sun.COM if (buf_size < SVCCTL_ENUMSERVICES_MINBUFSIZE) {
7787961SNatalie.Li@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed;
7797961SNatalie.Li@Sun.COM param->svc_num = 0;
78010001SJoyce.McIntosh@Sun.COM if (param->resume_handle)
78110001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0;
7827961SNatalie.Li@Sun.COM param->status = ERROR_MORE_DATA;
7838334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
7847961SNatalie.Li@Sun.COM }
7857961SNatalie.Li@Sun.COM
78610001SJoyce.McIntosh@Sun.COM svc_num = svcctl_scm_enum_services(mgr_ctx, param->services,
78710001SJoyce.McIntosh@Sun.COM buf_size, &resume_handle, B_TRUE);
78810001SJoyce.McIntosh@Sun.COM
78910001SJoyce.McIntosh@Sun.COM param->buf_size = buf_size;
79010001SJoyce.McIntosh@Sun.COM param->svc_num = svc_num;
7917961SNatalie.Li@Sun.COM
79210001SJoyce.McIntosh@Sun.COM if (resume_handle != 0) {
79310001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL)
79410001SJoyce.McIntosh@Sun.COM *param->resume_handle = resume_handle;
79510001SJoyce.McIntosh@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed;
79610001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA;
79710001SJoyce.McIntosh@Sun.COM } else {
79810001SJoyce.McIntosh@Sun.COM if (param->resume_handle)
79910001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0;
80010001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0;
80110001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
80210001SJoyce.McIntosh@Sun.COM }
80310001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
80410001SJoyce.McIntosh@Sun.COM
80510001SJoyce.McIntosh@Sun.COM enum_services_status_error:
80610001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumServicesStatus));
80710001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, "");
80810001SJoyce.McIntosh@Sun.COM param->status = status;
8098334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8107961SNatalie.Li@Sun.COM }
8117961SNatalie.Li@Sun.COM
8127961SNatalie.Li@Sun.COM /*
8137961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceConfig
8147961SNatalie.Li@Sun.COM *
8157961SNatalie.Li@Sun.COM * Returns:
8167961SNatalie.Li@Sun.COM * ERROR_SUCCESS
8177961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE
8187961SNatalie.Li@Sun.COM */
8197961SNatalie.Li@Sun.COM static int
svcctl_s_QueryServiceConfig(void * arg,ndr_xa_t * mxa)8208334SJose.Borrego@Sun.COM svcctl_s_QueryServiceConfig(void *arg, ndr_xa_t *mxa)
8217961SNatalie.Li@Sun.COM {
8227961SNatalie.Li@Sun.COM struct svcctl_QueryServiceConfig *param = arg;
8237961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
8247961SNatalie.Li@Sun.COM ndr_handle_t *hd;
8257961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
8267961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx;
8277961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc;
8287961SNatalie.Li@Sun.COM int bytes_needed = 0;
8297961SNatalie.Li@Sun.COM svc_config_t *cfg;
8307961SNatalie.Li@Sun.COM
8317961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
8327961SNatalie.Li@Sun.COM if (hd == NULL) {
8337961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig));
8347961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
8358334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8367961SNatalie.Li@Sun.COM }
8377961SNatalie.Li@Sun.COM
8387961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc;
8397961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid);
8407961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) {
8417961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig));
8427961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
8438334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8447961SNatalie.Li@Sun.COM }
8457961SNatalie.Li@Sun.COM
8467961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname);
8477961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_fmri == NULL) {
8487961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig));
8497961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST;
8508334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8517961SNatalie.Li@Sun.COM }
8527961SNatalie.Li@Sun.COM
8537961SNatalie.Li@Sun.COM cfg = ¶m->service_cfg;
8547961SNatalie.Li@Sun.COM cfg->service_type = SERVICE_WIN32_SHARE_PROCESS;
8557961SNatalie.Li@Sun.COM cfg->start_type = SERVICE_AUTO_START;
85610504SKeyur.Desai@Sun.COM cfg->error_control = SERVICE_ERROR_IGNORE;
8578334SJose.Borrego@Sun.COM cfg->binary_pathname = NDR_STRDUP(mxa, "");
8588334SJose.Borrego@Sun.COM cfg->loadorder_group = NDR_STRDUP(mxa, "");
8597961SNatalie.Li@Sun.COM cfg->tag_id = 0;
8608334SJose.Borrego@Sun.COM cfg->dependencies = NDR_STRDUP(mxa, "");
8618334SJose.Borrego@Sun.COM cfg->service_startname = NDR_STRDUP(mxa, "");
8628334SJose.Borrego@Sun.COM cfg->display_name = NDR_STRDUP(mxa, svc->sn_fmri);
8637961SNatalie.Li@Sun.COM
8647961SNatalie.Li@Sun.COM bytes_needed = sizeof (svc_config_t);
8657961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->binary_pathname);
8667961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->loadorder_group);
8677961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->dependencies);
8687961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->service_startname);
8697961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN(svc->sn_fmri);
8707961SNatalie.Li@Sun.COM
8717961SNatalie.Li@Sun.COM if (param->buf_size < bytes_needed) {
8727961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig));
8737961SNatalie.Li@Sun.COM param->cfg_bytes = bytes_needed;
87410001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER;
8758334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8767961SNatalie.Li@Sun.COM }
8777961SNatalie.Li@Sun.COM
8787961SNatalie.Li@Sun.COM param->cfg_bytes = bytes_needed;
8797961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS;
8808334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
8817961SNatalie.Li@Sun.COM }
8827961SNatalie.Li@Sun.COM
8837961SNatalie.Li@Sun.COM /*
88410001SJoyce.McIntosh@Sun.COM * svcctl_s_StartService
88510001SJoyce.McIntosh@Sun.COM */
88610001SJoyce.McIntosh@Sun.COM static int
svcctl_s_StartService(void * arg,ndr_xa_t * mxa)88710001SJoyce.McIntosh@Sun.COM svcctl_s_StartService(void *arg, ndr_xa_t *mxa)
88810001SJoyce.McIntosh@Sun.COM {
88910001SJoyce.McIntosh@Sun.COM struct svcctl_StartService *param = arg;
89010001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
89110001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
89210001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx;
89310001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx;
89410001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc;
89510001SJoyce.McIntosh@Sun.COM
89610001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
89710001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
89810001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE;
89910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
90010001SJoyce.McIntosh@Sun.COM }
90110001SJoyce.McIntosh@Sun.COM
90210001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc;
90310001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid);
90410001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) {
90510001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE;
90610001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
90710001SJoyce.McIntosh@Sun.COM }
90810001SJoyce.McIntosh@Sun.COM
90910001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname);
91010001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_fmri == NULL)
91110001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST;
91210001SJoyce.McIntosh@Sun.COM else
91310001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_ALREADY_RUNNING;
91410001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
91510001SJoyce.McIntosh@Sun.COM }
91610001SJoyce.McIntosh@Sun.COM
91710001SJoyce.McIntosh@Sun.COM
91810001SJoyce.McIntosh@Sun.COM /*
9197961SNatalie.Li@Sun.COM * svcctl_s_GetServiceDisplayNameW
9207961SNatalie.Li@Sun.COM *
9217961SNatalie.Li@Sun.COM * Returns:
9227961SNatalie.Li@Sun.COM * ERROR_SUCCESS
9237961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE
9247961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST
9257961SNatalie.Li@Sun.COM */
9267961SNatalie.Li@Sun.COM static int
svcctl_s_GetServiceDisplayNameW(void * arg,ndr_xa_t * mxa)9278334SJose.Borrego@Sun.COM svcctl_s_GetServiceDisplayNameW(void *arg, ndr_xa_t *mxa)
9287961SNatalie.Li@Sun.COM {
9297961SNatalie.Li@Sun.COM struct svcctl_GetServiceDisplayNameW *param = arg;
9307961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle;
9317961SNatalie.Li@Sun.COM ndr_handle_t *hd;
9327961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc;
9337961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
9347961SNatalie.Li@Sun.COM
9357961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT);
9367961SNatalie.Li@Sun.COM if (hd == NULL) {
9377961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW));
9388334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, "");
9397961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
9408334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9417961SNatalie.Li@Sun.COM }
9427961SNatalie.Li@Sun.COM
9437961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr;
9447961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, (char *)param->service_name);
9457961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_fmri == NULL) {
9467961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW));
9478334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, "");
9487961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST;
9498334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9507961SNatalie.Li@Sun.COM }
9517961SNatalie.Li@Sun.COM
9528334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, svc->sn_fmri);
9537961SNatalie.Li@Sun.COM if (param->display_name == NULL) {
9547961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW));
9558334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, "");
9567961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY;
9578334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9587961SNatalie.Li@Sun.COM }
9597961SNatalie.Li@Sun.COM
9607961SNatalie.Li@Sun.COM param->buf_size = strlen(svc->sn_fmri);
9617961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS;
9628334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9637961SNatalie.Li@Sun.COM }
9647961SNatalie.Li@Sun.COM
9657961SNatalie.Li@Sun.COM /*
9667961SNatalie.Li@Sun.COM * svcctl_s_GetServiceKeyNameW
9677961SNatalie.Li@Sun.COM *
9687961SNatalie.Li@Sun.COM * Returns:
9697961SNatalie.Li@Sun.COM * ERROR_SUCCESS
9707961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE
9717961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST
9727961SNatalie.Li@Sun.COM */
9737961SNatalie.Li@Sun.COM static int
svcctl_s_GetServiceKeyNameW(void * arg,ndr_xa_t * mxa)9748334SJose.Borrego@Sun.COM svcctl_s_GetServiceKeyNameW(void *arg, ndr_xa_t *mxa)
9757961SNatalie.Li@Sun.COM {
9767961SNatalie.Li@Sun.COM struct svcctl_GetServiceKeyNameW *param = arg;
9777961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle;
9787961SNatalie.Li@Sun.COM ndr_handle_t *hd;
9797961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc;
9807961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
9817961SNatalie.Li@Sun.COM
9827961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT);
9837961SNatalie.Li@Sun.COM if (hd == NULL) {
9847961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW));
9858334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, "");
9867961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
9878334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9887961SNatalie.Li@Sun.COM }
9897961SNatalie.Li@Sun.COM
9907961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr;
9917961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, (char *)param->service_name);
9927961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_name == NULL) {
9937961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW));
9948334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, "");
9957961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST;
9968334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
9977961SNatalie.Li@Sun.COM }
9987961SNatalie.Li@Sun.COM
9998334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, svc->sn_name);
10007961SNatalie.Li@Sun.COM if (param->key_name == NULL) {
10017961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW));
10028334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, "");
10037961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY;
10048334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
10057961SNatalie.Li@Sun.COM }
10067961SNatalie.Li@Sun.COM
10077961SNatalie.Li@Sun.COM param->buf_size = strlen(svc->sn_name);
10087961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS;
10098334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
10107961SNatalie.Li@Sun.COM }
10117961SNatalie.Li@Sun.COM
10127961SNatalie.Li@Sun.COM /*
101310001SJoyce.McIntosh@Sun.COM * svcctl_s_OpenSCManagerA
101410001SJoyce.McIntosh@Sun.COM *
101510001SJoyce.McIntosh@Sun.COM * Request to open the service control manager.
101610001SJoyce.McIntosh@Sun.COM * The caller must have administrator rights in order to open this
101710001SJoyce.McIntosh@Sun.COM * interface. We don't support write (SC_MANAGER_LOCK) access.
101810001SJoyce.McIntosh@Sun.COM *
101910001SJoyce.McIntosh@Sun.COM * Returns:
102010001SJoyce.McIntosh@Sun.COM * ERROR_SUCCESS
102110001SJoyce.McIntosh@Sun.COM * ERROR_ACCESS_DENIED
102210001SJoyce.McIntosh@Sun.COM *
102310001SJoyce.McIntosh@Sun.COM * On success, returns a handle for use with subsequent svcctl requests.
102410001SJoyce.McIntosh@Sun.COM */
102510001SJoyce.McIntosh@Sun.COM static int
svcctl_s_OpenSCManagerA(void * arg,ndr_xa_t * mxa)102610001SJoyce.McIntosh@Sun.COM svcctl_s_OpenSCManagerA(void *arg, ndr_xa_t *mxa)
102710001SJoyce.McIntosh@Sun.COM {
102810001SJoyce.McIntosh@Sun.COM struct svcctl_OpenSCManagerA *param = arg;
102910001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = NULL;
103010001SJoyce.McIntosh@Sun.COM int rc;
103110001SJoyce.McIntosh@Sun.COM
103210001SJoyce.McIntosh@Sun.COM rc = ndr_is_admin(mxa);
103310001SJoyce.McIntosh@Sun.COM
103410001SJoyce.McIntosh@Sun.COM if ((rc == 0) || (param->desired_access & SC_MANAGER_LOCK) != 0) {
103510001SJoyce.McIntosh@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t));
103610001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED;
103710001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
103810001SJoyce.McIntosh@Sun.COM }
103910001SJoyce.McIntosh@Sun.COM
104010001SJoyce.McIntosh@Sun.COM id = svcctl_mgr_hdalloc(mxa);
104110001SJoyce.McIntosh@Sun.COM if (id) {
104210001SJoyce.McIntosh@Sun.COM bcopy(id, ¶m->handle, sizeof (svcctl_handle_t));
104310001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
104410001SJoyce.McIntosh@Sun.COM } else {
104510001SJoyce.McIntosh@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t));
104610001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED;
104710001SJoyce.McIntosh@Sun.COM }
104810001SJoyce.McIntosh@Sun.COM
104910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
105010001SJoyce.McIntosh@Sun.COM }
105110001SJoyce.McIntosh@Sun.COM
105210001SJoyce.McIntosh@Sun.COM /*
105310001SJoyce.McIntosh@Sun.COM * svcctl_s_OpenServiceA
105410001SJoyce.McIntosh@Sun.COM *
105510001SJoyce.McIntosh@Sun.COM * Return a handle for use with subsequent svcctl requests.
105610001SJoyce.McIntosh@Sun.COM *
105710001SJoyce.McIntosh@Sun.COM * Returns:
105810001SJoyce.McIntosh@Sun.COM * ERROR_SUCCESS
105910001SJoyce.McIntosh@Sun.COM * ERROR_INVALID_HANDLE
106010001SJoyce.McIntosh@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST
106110001SJoyce.McIntosh@Sun.COM * ERROR_CALL_NOT_IMPLEMENTED
106210001SJoyce.McIntosh@Sun.COM */
106310001SJoyce.McIntosh@Sun.COM static int
svcctl_s_OpenServiceA(void * arg,ndr_xa_t * mxa)106410001SJoyce.McIntosh@Sun.COM svcctl_s_OpenServiceA(void *arg, ndr_xa_t *mxa)
106510001SJoyce.McIntosh@Sun.COM {
106610001SJoyce.McIntosh@Sun.COM struct svcctl_OpenServiceA *param = arg;
106710001SJoyce.McIntosh@Sun.COM ndr_hdid_t *mgrid = (ndr_hdid_t *)¶m->manager_handle;
106810001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = NULL;
106910001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
107010001SJoyce.McIntosh@Sun.COM DWORD status;
107110001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx;
107210001SJoyce.McIntosh@Sun.COM char *svc_name = (char *)param->service_name->value;
107310001SJoyce.McIntosh@Sun.COM boolean_t unimplemented_operations = B_FALSE;
107410001SJoyce.McIntosh@Sun.COM
107510001SJoyce.McIntosh@Sun.COM /* Allow service handle allocations for only status & config queries */
107610001SJoyce.McIntosh@Sun.COM unimplemented_operations =
107710001SJoyce.McIntosh@Sun.COM SVCCTL_OPENSVC_OP_UNIMPLEMENTED(param->desired_access);
107810001SJoyce.McIntosh@Sun.COM
107910001SJoyce.McIntosh@Sun.COM if (unimplemented_operations) {
108010001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t));
108110001SJoyce.McIntosh@Sun.COM param->status = ERROR_CALL_NOT_IMPLEMENTED;
108210001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
108310001SJoyce.McIntosh@Sun.COM }
108410001SJoyce.McIntosh@Sun.COM
108510001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, mgrid, SVCCTL_MANAGER_CONTEXT);
108610001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
108710001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t));
108810001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE;
108910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
109010001SJoyce.McIntosh@Sun.COM }
109110001SJoyce.McIntosh@Sun.COM
109210001SJoyce.McIntosh@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr;
109310001SJoyce.McIntosh@Sun.COM status = svcctl_scm_validate_service(mgr_ctx, svc_name);
109410001SJoyce.McIntosh@Sun.COM if (status != ERROR_SUCCESS) {
109510001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t));
109610001SJoyce.McIntosh@Sun.COM param->status = status;
109710001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
109810001SJoyce.McIntosh@Sun.COM }
109910001SJoyce.McIntosh@Sun.COM
110010001SJoyce.McIntosh@Sun.COM id = svcctl_svc_hdalloc(mxa, mgrid, svc_name);
110110001SJoyce.McIntosh@Sun.COM if (id) {
110210001SJoyce.McIntosh@Sun.COM bcopy(id, ¶m->service_handle, sizeof (svcctl_handle_t));
110310001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
110410001SJoyce.McIntosh@Sun.COM } else {
110510001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t));
110610001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED;
110710001SJoyce.McIntosh@Sun.COM }
110810001SJoyce.McIntosh@Sun.COM
110910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
111010001SJoyce.McIntosh@Sun.COM }
111110001SJoyce.McIntosh@Sun.COM
111210001SJoyce.McIntosh@Sun.COM /*
111310001SJoyce.McIntosh@Sun.COM * svcctl_s_EnumServicesStatusA
111410001SJoyce.McIntosh@Sun.COM *
111510001SJoyce.McIntosh@Sun.COM * Enumerate the list of services we support as ASCII.
111610001SJoyce.McIntosh@Sun.COM */
111710001SJoyce.McIntosh@Sun.COM static int
svcctl_s_EnumServicesStatusA(void * arg,ndr_xa_t * mxa)111810001SJoyce.McIntosh@Sun.COM svcctl_s_EnumServicesStatusA(void *arg, ndr_xa_t *mxa)
111910001SJoyce.McIntosh@Sun.COM {
112010001SJoyce.McIntosh@Sun.COM struct svcctl_EnumServicesStatusA *param = arg;
112110001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle;
112210001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
112310001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx;
112410001SJoyce.McIntosh@Sun.COM uint32_t buf_size;
112510001SJoyce.McIntosh@Sun.COM uint32_t svc_num;
112610001SJoyce.McIntosh@Sun.COM uint32_t resume_handle = 0;
112710001SJoyce.McIntosh@Sun.COM uint32_t status;
112810001SJoyce.McIntosh@Sun.COM
112910001SJoyce.McIntosh@Sun.COM buf_size = param->buf_size;
113010001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL)
113110001SJoyce.McIntosh@Sun.COM resume_handle = *param->resume_handle;
113210001SJoyce.McIntosh@Sun.COM
113310001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT);
113410001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
113510001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
113610001SJoyce.McIntosh@Sun.COM goto enum_services_status_error;
113710001SJoyce.McIntosh@Sun.COM }
113810001SJoyce.McIntosh@Sun.COM
113910001SJoyce.McIntosh@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr;
114010001SJoyce.McIntosh@Sun.COM if (svcctl_scm_refresh(mgr_ctx) != 0) {
114110001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
114210001SJoyce.McIntosh@Sun.COM goto enum_services_status_error;
114310001SJoyce.McIntosh@Sun.COM }
114410001SJoyce.McIntosh@Sun.COM
114510001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, buf_size);
114610001SJoyce.McIntosh@Sun.COM if (param->services == NULL) {
114710001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY;
114810001SJoyce.McIntosh@Sun.COM goto enum_services_status_error;
114910001SJoyce.McIntosh@Sun.COM }
115010001SJoyce.McIntosh@Sun.COM bzero(param->services, buf_size);
115110001SJoyce.McIntosh@Sun.COM
115210001SJoyce.McIntosh@Sun.COM svc_num = svcctl_scm_enum_services(mgr_ctx, param->services,
115310001SJoyce.McIntosh@Sun.COM buf_size, &resume_handle, B_FALSE);
115410001SJoyce.McIntosh@Sun.COM
115510001SJoyce.McIntosh@Sun.COM param->buf_size = buf_size;
115610001SJoyce.McIntosh@Sun.COM param->svc_num = svc_num;
115710001SJoyce.McIntosh@Sun.COM
115810001SJoyce.McIntosh@Sun.COM if (resume_handle != 0) {
115910001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL)
116010001SJoyce.McIntosh@Sun.COM *param->resume_handle = resume_handle;
116110001SJoyce.McIntosh@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed;
116210001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA;
116310001SJoyce.McIntosh@Sun.COM } else {
116410001SJoyce.McIntosh@Sun.COM if (param->resume_handle)
116510001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0;
116610001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0;
116710001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
116810001SJoyce.McIntosh@Sun.COM }
116910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
117010001SJoyce.McIntosh@Sun.COM
117110001SJoyce.McIntosh@Sun.COM enum_services_status_error:
117210001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumServicesStatusA));
117310001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, "");
117410001SJoyce.McIntosh@Sun.COM param->status = status;
117510001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
117610001SJoyce.McIntosh@Sun.COM }
117710001SJoyce.McIntosh@Sun.COM
117810001SJoyce.McIntosh@Sun.COM /*
11797961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceConfig2W
11807961SNatalie.Li@Sun.COM *
11817961SNatalie.Li@Sun.COM * Returns:
11827961SNatalie.Li@Sun.COM * ERROR_SUCCESS
11837961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE
11847961SNatalie.Li@Sun.COM * ERROR_INVALID_LEVEL
11857961SNatalie.Li@Sun.COM * ERROR_NOT_ENOUGH_MEMORY
11867961SNatalie.Li@Sun.COM */
11877961SNatalie.Li@Sun.COM static int
svcctl_s_QueryServiceConfig2W(void * arg,ndr_xa_t * mxa)11888334SJose.Borrego@Sun.COM svcctl_s_QueryServiceConfig2W(void *arg, ndr_xa_t *mxa)
11897961SNatalie.Li@Sun.COM {
11907961SNatalie.Li@Sun.COM struct svcctl_QueryServiceConfig2W *param = arg;
11917961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
11927961SNatalie.Li@Sun.COM ndr_handle_t *hd;
11937961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx;
11947961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx;
11957961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc;
119610504SKeyur.Desai@Sun.COM svc_config_rsp_t svc_rsp;
11977961SNatalie.Li@Sun.COM int offset, input_bufsize, bytes_needed = 0;
119810966SJordan.Brown@Sun.COM smb_wchar_t *wide_desc;
11997961SNatalie.Li@Sun.COM char *desc;
12007961SNatalie.Li@Sun.COM DWORD status;
12017961SNatalie.Li@Sun.COM
12027961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
12037961SNatalie.Li@Sun.COM if (hd == NULL) {
12047961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W));
12058334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, "");
12067961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
12078334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
12087961SNatalie.Li@Sun.COM }
12097961SNatalie.Li@Sun.COM
12107961SNatalie.Li@Sun.COM input_bufsize = param->buf_size;
12118334SJose.Borrego@Sun.COM param->buffer = NDR_MALLOC(mxa, input_bufsize);
12127961SNatalie.Li@Sun.COM if (param->buffer == NULL) {
12137961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W));
12148334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, "");
12157961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY;
12168334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
12177961SNatalie.Li@Sun.COM }
12187961SNatalie.Li@Sun.COM bzero(param->buffer, input_bufsize);
12197961SNatalie.Li@Sun.COM
122010504SKeyur.Desai@Sun.COM svc_rsp.svc_buf = param->buffer;
12217961SNatalie.Li@Sun.COM status = ERROR_SUCCESS;
12227961SNatalie.Li@Sun.COM switch (param->info_level) {
12237961SNatalie.Li@Sun.COM case SERVICE_CONFIG_DESCRIPTION:
12247961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc;
12257961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid);
12267961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) {
12277961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE;
12287961SNatalie.Li@Sun.COM break;
12297961SNatalie.Li@Sun.COM }
12307961SNatalie.Li@Sun.COM
12317961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname);
12327961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_desc == NULL) {
12337961SNatalie.Li@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST;
12347961SNatalie.Li@Sun.COM break;
12357961SNatalie.Li@Sun.COM }
12367961SNatalie.Li@Sun.COM
12377961SNatalie.Li@Sun.COM desc = svc->sn_desc;
12387961SNatalie.Li@Sun.COM bytes_needed = SVCCTL_WNSTRLEN(desc);
12397961SNatalie.Li@Sun.COM
12407961SNatalie.Li@Sun.COM if (input_bufsize <= bytes_needed) {
12417961SNatalie.Li@Sun.COM param->bytes_needed = bytes_needed;
124210001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER;
12438334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
12447961SNatalie.Li@Sun.COM }
12457961SNatalie.Li@Sun.COM
12467961SNatalie.Li@Sun.COM offset = sizeof (svc_description_t);
124710504SKeyur.Desai@Sun.COM svc_rsp.svc_desc->desc = offset;
12487961SNatalie.Li@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/
124910966SJordan.Brown@Sun.COM wide_desc = (smb_wchar_t *)¶m->buffer[offset];
125010966SJordan.Brown@Sun.COM (void) smb_mbstowcs(wide_desc, desc, (strlen(desc) + 1));
125110504SKeyur.Desai@Sun.COM offset += SVCCTL_WNSTRLEN(desc);
12527961SNatalie.Li@Sun.COM
12537961SNatalie.Li@Sun.COM param->bytes_needed = offset;
12547961SNatalie.Li@Sun.COM break;
12557961SNatalie.Li@Sun.COM
12567961SNatalie.Li@Sun.COM case SERVICE_CONFIG_FAILURE_ACTIONS:
125710504SKeyur.Desai@Sun.COM bzero(svc_rsp.svc_fac, sizeof (svc_failure_actions_t));
125810504SKeyur.Desai@Sun.COM bytes_needed = sizeof (svc_failure_actions_t);
125910504SKeyur.Desai@Sun.COM if (input_bufsize <= bytes_needed) {
126010504SKeyur.Desai@Sun.COM param->bytes_needed = bytes_needed;
126110504SKeyur.Desai@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER;
126210504SKeyur.Desai@Sun.COM return (NDR_DRC_OK);
126310504SKeyur.Desai@Sun.COM }
126410504SKeyur.Desai@Sun.COM param->bytes_needed = bytes_needed;
12657961SNatalie.Li@Sun.COM break;
12667961SNatalie.Li@Sun.COM
126710504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_DELAYED_AUTO_START_INFO:
126810504SKeyur.Desai@Sun.COM svc_rsp.svc_dstart->dstart = 0;
126910504SKeyur.Desai@Sun.COM param->bytes_needed = sizeof (svc_delayed_auto_start_t);
127010504SKeyur.Desai@Sun.COM break;
127110504SKeyur.Desai@Sun.COM
127210504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_FAILURE_ACTIONS_FLAG:
127310504SKeyur.Desai@Sun.COM svc_rsp.svc_cfa->cfa = 0;
127410504SKeyur.Desai@Sun.COM param->bytes_needed = sizeof (svc_config_failure_action_t);
127510504SKeyur.Desai@Sun.COM break;
127610504SKeyur.Desai@Sun.COM
127710504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_SERVICE_SID_INFO:
127810504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO:
127910504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_PRESHUTDOWN_INFO:
128010504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_TRIGGER_INFO:
128110504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_PREFERRED_NODE:
12827961SNatalie.Li@Sun.COM default:
12837961SNatalie.Li@Sun.COM status = ERROR_INVALID_LEVEL;
12847961SNatalie.Li@Sun.COM break;
12857961SNatalie.Li@Sun.COM }
12867961SNatalie.Li@Sun.COM
12877961SNatalie.Li@Sun.COM if (status != ERROR_SUCCESS) {
12887961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W));
12898334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, "");
12907961SNatalie.Li@Sun.COM param->status = status;
12918334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
12927961SNatalie.Li@Sun.COM }
12937961SNatalie.Li@Sun.COM
12947961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS;
12958334SJose.Borrego@Sun.COM return (NDR_DRC_OK);
12967961SNatalie.Li@Sun.COM }
129710001SJoyce.McIntosh@Sun.COM
129810001SJoyce.McIntosh@Sun.COM /*
129910001SJoyce.McIntosh@Sun.COM * svcctl_s_QueryServiceStatusEx
130010001SJoyce.McIntosh@Sun.COM */
130110001SJoyce.McIntosh@Sun.COM static int
svcctl_s_QueryServiceStatusEx(void * arg,ndr_xa_t * mxa)130210001SJoyce.McIntosh@Sun.COM svcctl_s_QueryServiceStatusEx(void *arg, ndr_xa_t *mxa)
130310001SJoyce.McIntosh@Sun.COM {
130410001SJoyce.McIntosh@Sun.COM struct svcctl_QueryServiceStatusEx *param = arg;
130510001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle;
130610001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd;
130710001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx;
130810001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx;
130910001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc;
131010001SJoyce.McIntosh@Sun.COM svc_status_ex_t *svc_status_ex;
131110001SJoyce.McIntosh@Sun.COM uint32_t input_bufsize;
131210001SJoyce.McIntosh@Sun.COM uint32_t bytes_needed;
131310001SJoyce.McIntosh@Sun.COM DWORD status;
131410001SJoyce.McIntosh@Sun.COM
131510001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT);
131610001SJoyce.McIntosh@Sun.COM if (hd == NULL) {
131710001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
131810001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error;
131910001SJoyce.McIntosh@Sun.COM }
132010001SJoyce.McIntosh@Sun.COM
132110001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc;
132210001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid);
132310001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) {
132410001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE;
132510001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error;
132610001SJoyce.McIntosh@Sun.COM }
132710001SJoyce.McIntosh@Sun.COM
132810001SJoyce.McIntosh@Sun.COM if (param->info_level != SC_STATUS_PROCESS_INFO) {
132910001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER;
133010001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error;
133110001SJoyce.McIntosh@Sun.COM }
133210001SJoyce.McIntosh@Sun.COM
133310504SKeyur.Desai@Sun.COM bytes_needed = sizeof (svc_status_ex_t);
133410001SJoyce.McIntosh@Sun.COM
133510001SJoyce.McIntosh@Sun.COM if ((input_bufsize = param->buf_size) < bytes_needed) {
133610001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatusEx));
133710001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize;
133810001SJoyce.McIntosh@Sun.COM param->buffer = NDR_STRDUP(mxa, "");
133910001SJoyce.McIntosh@Sun.COM param->bytes_needed = bytes_needed;
134010001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER;
134110001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
134210001SJoyce.McIntosh@Sun.COM }
134310001SJoyce.McIntosh@Sun.COM
134410001SJoyce.McIntosh@Sun.COM if ((svc_status_ex = NDR_MALLOC(mxa, bytes_needed)) == NULL) {
134510001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY;
134610001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error;
134710001SJoyce.McIntosh@Sun.COM }
134810001SJoyce.McIntosh@Sun.COM
134910001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname);
135010001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) {
135110001SJoyce.McIntosh@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST;
135210001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error;
135310001SJoyce.McIntosh@Sun.COM }
135410001SJoyce.McIntosh@Sun.COM
135510001SJoyce.McIntosh@Sun.COM svc_status_ex->service_type = SERVICE_WIN32_SHARE_PROCESS;
135610001SJoyce.McIntosh@Sun.COM svc_status_ex->cur_state = svcctl_scm_map_status(svc->sn_state);
135710001SJoyce.McIntosh@Sun.COM svc_status_ex->ctrl_accepted = 0;
135810001SJoyce.McIntosh@Sun.COM svc_status_ex->w32_exitcode = 0;
135910001SJoyce.McIntosh@Sun.COM svc_status_ex->svc_specified_exitcode = 0;
136010001SJoyce.McIntosh@Sun.COM svc_status_ex->check_point = 0;
136110001SJoyce.McIntosh@Sun.COM svc_status_ex->wait_hint = 0;
136210001SJoyce.McIntosh@Sun.COM svc_status_ex->process_id = 1;
136310001SJoyce.McIntosh@Sun.COM svc_status_ex->service_flags = 1;
136410001SJoyce.McIntosh@Sun.COM
136510001SJoyce.McIntosh@Sun.COM param->buffer = (uint8_t *)svc_status_ex;
136610504SKeyur.Desai@Sun.COM param->buf_size = input_bufsize;
136710504SKeyur.Desai@Sun.COM param->bytes_needed = bytes_needed;
136810001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS;
136910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
137010001SJoyce.McIntosh@Sun.COM
137110001SJoyce.McIntosh@Sun.COM query_service_status_ex_error:
137210001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatusEx));
137310001SJoyce.McIntosh@Sun.COM param->buffer = NDR_STRDUP(mxa, "");
137410001SJoyce.McIntosh@Sun.COM param->status = status;
137510001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK);
137610001SJoyce.McIntosh@Sun.COM }
1377