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 */ 217961SNatalie.Li@Sun.COM /* 22*10001SJoyce.McIntosh@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237961SNatalie.Li@Sun.COM * Use is subject to license terms. 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> 377961SNatalie.Li@Sun.COM #include <smbsrv/ntstatus.h> 387961SNatalie.Li@Sun.COM #include <smbsrv/nmpipes.h> 39*10001SJoyce.McIntosh@Sun.COM #include <smbsrv/ntifs.h> 407961SNatalie.Li@Sun.COM #include "svcctl_scm.h" 417961SNatalie.Li@Sun.COM 42*10001SJoyce.McIntosh@Sun.COM #define SVCCTL_SECURITY_BUFSIZE 256 43*10001SJoyce.McIntosh@Sun.COM #define SVCCTL_ENUMSERVICES_MINBUFSIZE 1024 44*10001SJoyce.McIntosh@Sun.COM 457961SNatalie.Li@Sun.COM #define SVCCTL_OPENSVC_OP_UNIMPLEMENTED(S) \ 467961SNatalie.Li@Sun.COM ((S) & SERVICE_CHANGE_CONFIG) || \ 477961SNatalie.Li@Sun.COM ((S) & SERVICE_PAUSE_CONTINUE) || \ 487961SNatalie.Li@Sun.COM ((S) & SERVICE_START) || \ 497961SNatalie.Li@Sun.COM ((S) & SERVICE_STOP) || \ 507961SNatalie.Li@Sun.COM ((S) & SERVICE_ENUMERATE_DEPENDENTS) 517961SNatalie.Li@Sun.COM 528334SJose.Borrego@Sun.COM static int svcctl_s_Close(void *, ndr_xa_t *); 53*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_ControlService(void *, ndr_xa_t *); 54*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_DeleteService(void *, ndr_xa_t *); 55*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_QueryServiceSecurity(void *, ndr_xa_t *); 56*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_SetServiceSecurity(void *, ndr_xa_t *); 578334SJose.Borrego@Sun.COM static int svcctl_s_OpenManager(void *, ndr_xa_t *); 588334SJose.Borrego@Sun.COM static int svcctl_s_OpenService(void *, ndr_xa_t *); 598334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceStatus(void *, ndr_xa_t *); 608334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceConfig(void *, ndr_xa_t *); 61*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_StartService(void *, ndr_xa_t *); 62*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_EnumDependentServices(void *, ndr_xa_t *); 638334SJose.Borrego@Sun.COM static int svcctl_s_EnumServicesStatus(void *, ndr_xa_t *); 648334SJose.Borrego@Sun.COM static int svcctl_s_GetServiceDisplayNameW(void *, ndr_xa_t *); 658334SJose.Borrego@Sun.COM static int svcctl_s_GetServiceKeyNameW(void *, ndr_xa_t *); 66*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_OpenSCManagerA(void *, ndr_xa_t *); 67*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_OpenServiceA(void *, ndr_xa_t *); 68*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_EnumServicesStatusA(void *, ndr_xa_t *); 698334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceConfig2W(void *, ndr_xa_t *); 70*10001SJoyce.McIntosh@Sun.COM static int svcctl_s_QueryServiceStatusEx(void *, ndr_xa_t *); 717961SNatalie.Li@Sun.COM 728334SJose.Borrego@Sun.COM static ndr_stub_table_t svcctl_stub_table[] = { 737961SNatalie.Li@Sun.COM { svcctl_s_Close, SVCCTL_OPNUM_Close }, 74*10001SJoyce.McIntosh@Sun.COM { svcctl_s_ControlService, SVCCTL_OPNUM_ControlService }, 75*10001SJoyce.McIntosh@Sun.COM { svcctl_s_DeleteService, SVCCTL_OPNUM_DeleteService }, 76*10001SJoyce.McIntosh@Sun.COM { svcctl_s_QueryServiceSecurity, SVCCTL_OPNUM_QueryServiceSecurity }, 77*10001SJoyce.McIntosh@Sun.COM { svcctl_s_SetServiceSecurity, SVCCTL_OPNUM_SetServiceSecurity }, 787961SNatalie.Li@Sun.COM { svcctl_s_OpenManager, SVCCTL_OPNUM_OpenManager }, 797961SNatalie.Li@Sun.COM { svcctl_s_OpenService, SVCCTL_OPNUM_OpenService }, 807961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceStatus, SVCCTL_OPNUM_QueryServiceStatus }, 817961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceConfig, SVCCTL_OPNUM_QueryServiceConfig }, 82*10001SJoyce.McIntosh@Sun.COM { svcctl_s_StartService, SVCCTL_OPNUM_StartService }, 83*10001SJoyce.McIntosh@Sun.COM { svcctl_s_EnumDependentServices, 84*10001SJoyce.McIntosh@Sun.COM SVCCTL_OPNUM_EnumDependentServices }, 857961SNatalie.Li@Sun.COM { svcctl_s_EnumServicesStatus, SVCCTL_OPNUM_EnumServicesStatus }, 867961SNatalie.Li@Sun.COM { svcctl_s_GetServiceDisplayNameW, 877961SNatalie.Li@Sun.COM SVCCTL_OPNUM_GetServiceDisplayNameW }, 887961SNatalie.Li@Sun.COM { svcctl_s_GetServiceKeyNameW, SVCCTL_OPNUM_GetServiceKeyNameW }, 89*10001SJoyce.McIntosh@Sun.COM { svcctl_s_OpenSCManagerA, SVCCTL_OPNUM_OpenSCManagerA }, 90*10001SJoyce.McIntosh@Sun.COM { svcctl_s_OpenServiceA, SVCCTL_OPNUM_OpenServiceA }, 91*10001SJoyce.McIntosh@Sun.COM { svcctl_s_EnumServicesStatusA, SVCCTL_OPNUM_EnumServicesStatusA }, 927961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceConfig2W, SVCCTL_OPNUM_QueryServiceConfig2W }, 93*10001SJoyce.McIntosh@Sun.COM { svcctl_s_QueryServiceStatusEx, SVCCTL_OPNUM_QueryServiceStatusEx }, 947961SNatalie.Li@Sun.COM {0} 957961SNatalie.Li@Sun.COM }; 967961SNatalie.Li@Sun.COM 978334SJose.Borrego@Sun.COM static ndr_service_t svcctl_service = { 987961SNatalie.Li@Sun.COM "SVCCTL", /* name */ 997961SNatalie.Li@Sun.COM "Service Control Services", /* desc */ 1007961SNatalie.Li@Sun.COM "\\svcctl", /* endpoint */ 1017961SNatalie.Li@Sun.COM PIPE_NTSVCS, /* sec_addr_port */ 1028334SJose.Borrego@Sun.COM "367abb81-9844-35f1-ad32-98f038001003", 2, /* abstract */ 1038334SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 1047961SNatalie.Li@Sun.COM 0, /* no bind_instance_size */ 1057961SNatalie.Li@Sun.COM 0, /* no bind_req() */ 1067961SNatalie.Li@Sun.COM 0, /* no unbind_and_close() */ 1077961SNatalie.Li@Sun.COM 0, /* use generic_call_stub() */ 1087961SNatalie.Li@Sun.COM &TYPEINFO(svcctl_interface), /* interface ti */ 1097961SNatalie.Li@Sun.COM svcctl_stub_table /* stub_table */ 1107961SNatalie.Li@Sun.COM }; 1117961SNatalie.Li@Sun.COM 1127961SNatalie.Li@Sun.COM /* 1137961SNatalie.Li@Sun.COM * svcctl_initialize 1147961SNatalie.Li@Sun.COM * 1157961SNatalie.Li@Sun.COM * This function registers the SVCCTL RPC interface with the RPC runtime 1167961SNatalie.Li@Sun.COM * library. It must be called in order to use either the client side 1177961SNatalie.Li@Sun.COM * or the server side functions. 1187961SNatalie.Li@Sun.COM */ 1197961SNatalie.Li@Sun.COM void 1207961SNatalie.Li@Sun.COM svcctl_initialize(void) 1217961SNatalie.Li@Sun.COM { 1228334SJose.Borrego@Sun.COM (void) ndr_svc_register(&svcctl_service); 1237961SNatalie.Li@Sun.COM } 1247961SNatalie.Li@Sun.COM 1257961SNatalie.Li@Sun.COM /* 1267961SNatalie.Li@Sun.COM * svcctl_hdlookup 1277961SNatalie.Li@Sun.COM * 1287961SNatalie.Li@Sun.COM * Handle lookup wrapper to validate the local service and/or manager context. 1297961SNatalie.Li@Sun.COM */ 1307961SNatalie.Li@Sun.COM static ndr_handle_t * 1317961SNatalie.Li@Sun.COM svcctl_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, svcctl_context_type_t type) 1327961SNatalie.Li@Sun.COM { 1337961SNatalie.Li@Sun.COM ndr_handle_t *hd; 1347961SNatalie.Li@Sun.COM svcctl_context_t *ctx; 1357961SNatalie.Li@Sun.COM 1367961SNatalie.Li@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) 1377961SNatalie.Li@Sun.COM return (NULL); 1387961SNatalie.Li@Sun.COM 1397961SNatalie.Li@Sun.COM if ((ctx = (svcctl_context_t *)hd->nh_data) == NULL) 1407961SNatalie.Li@Sun.COM return (NULL); 1417961SNatalie.Li@Sun.COM 1427961SNatalie.Li@Sun.COM if ((ctx->c_type != type) || (ctx->c_ctx.uc_cp == NULL)) 1437961SNatalie.Li@Sun.COM return (NULL); 1447961SNatalie.Li@Sun.COM 1457961SNatalie.Li@Sun.COM return (hd); 1467961SNatalie.Li@Sun.COM } 1477961SNatalie.Li@Sun.COM 1487961SNatalie.Li@Sun.COM /* 1497961SNatalie.Li@Sun.COM * svcctl_hdfree 1507961SNatalie.Li@Sun.COM * 1517961SNatalie.Li@Sun.COM * Handle deallocation wrapper to free the local service and/or manager context. 1527961SNatalie.Li@Sun.COM */ 1537961SNatalie.Li@Sun.COM static void 1547961SNatalie.Li@Sun.COM svcctl_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id) 1557961SNatalie.Li@Sun.COM { 1567961SNatalie.Li@Sun.COM ndr_handle_t *hd; 1577961SNatalie.Li@Sun.COM svcctl_context_t *ctx; 1587961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 1597961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 1607961SNatalie.Li@Sun.COM 1617961SNatalie.Li@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 1627961SNatalie.Li@Sun.COM ctx = (svcctl_context_t *)hd->nh_data; 1637961SNatalie.Li@Sun.COM 1647961SNatalie.Li@Sun.COM switch (ctx->c_type) { 1657961SNatalie.Li@Sun.COM case SVCCTL_MANAGER_CONTEXT: 1667961SNatalie.Li@Sun.COM mgr_ctx = ctx->c_ctx.uc_mgr; 1677961SNatalie.Li@Sun.COM svcctl_scm_fini(mgr_ctx); 1687961SNatalie.Li@Sun.COM svcctl_scm_scf_handle_fini(mgr_ctx); 1697961SNatalie.Li@Sun.COM free(mgr_ctx); 1707961SNatalie.Li@Sun.COM break; 1717961SNatalie.Li@Sun.COM 1727961SNatalie.Li@Sun.COM case SVCCTL_SERVICE_CONTEXT: 1737961SNatalie.Li@Sun.COM svc_ctx = ctx->c_ctx.uc_svc; 1747961SNatalie.Li@Sun.COM free(svc_ctx->sc_mgrid); 1757961SNatalie.Li@Sun.COM free(svc_ctx->sc_svcname); 1767961SNatalie.Li@Sun.COM free(svc_ctx); 1777961SNatalie.Li@Sun.COM break; 1787961SNatalie.Li@Sun.COM 1797961SNatalie.Li@Sun.COM default: 1807961SNatalie.Li@Sun.COM break; 1817961SNatalie.Li@Sun.COM } 1827961SNatalie.Li@Sun.COM 1837961SNatalie.Li@Sun.COM free(ctx); 1847961SNatalie.Li@Sun.COM ndr_hdfree(mxa, id); 1857961SNatalie.Li@Sun.COM } 1867961SNatalie.Li@Sun.COM } 1877961SNatalie.Li@Sun.COM 1887961SNatalie.Li@Sun.COM /* 1897961SNatalie.Li@Sun.COM * svcctl_mgr_hdalloc 1907961SNatalie.Li@Sun.COM * 1917961SNatalie.Li@Sun.COM * Handle allocation wrapper to setup the local manager context. 1927961SNatalie.Li@Sun.COM */ 1937961SNatalie.Li@Sun.COM static ndr_hdid_t * 1947961SNatalie.Li@Sun.COM svcctl_mgr_hdalloc(ndr_xa_t *mxa) 1957961SNatalie.Li@Sun.COM { 1967961SNatalie.Li@Sun.COM svcctl_context_t *ctx; 1977961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 1987961SNatalie.Li@Sun.COM 1997961SNatalie.Li@Sun.COM if ((ctx = malloc(sizeof (svcctl_context_t))) == NULL) 2007961SNatalie.Li@Sun.COM return (NULL); 2017961SNatalie.Li@Sun.COM ctx->c_type = SVCCTL_MANAGER_CONTEXT; 2027961SNatalie.Li@Sun.COM 2037961SNatalie.Li@Sun.COM if ((mgr_ctx = malloc(sizeof (svcctl_manager_context_t))) == NULL) { 2047961SNatalie.Li@Sun.COM free(ctx); 2057961SNatalie.Li@Sun.COM return (NULL); 2067961SNatalie.Li@Sun.COM } 2077961SNatalie.Li@Sun.COM bzero(mgr_ctx, sizeof (svcctl_manager_context_t)); 2087961SNatalie.Li@Sun.COM 2097961SNatalie.Li@Sun.COM if (svcctl_scm_scf_handle_init(mgr_ctx) < 0) { 2107961SNatalie.Li@Sun.COM free(mgr_ctx); 2117961SNatalie.Li@Sun.COM free(ctx); 2127961SNatalie.Li@Sun.COM return (NULL); 2137961SNatalie.Li@Sun.COM } 2147961SNatalie.Li@Sun.COM 2157961SNatalie.Li@Sun.COM if (svcctl_scm_init(mgr_ctx) < 0) { 2167961SNatalie.Li@Sun.COM svcctl_scm_scf_handle_fini(mgr_ctx); 2177961SNatalie.Li@Sun.COM free(mgr_ctx); 2187961SNatalie.Li@Sun.COM free(ctx); 2197961SNatalie.Li@Sun.COM return (NULL); 2207961SNatalie.Li@Sun.COM } 2217961SNatalie.Li@Sun.COM 2227961SNatalie.Li@Sun.COM ctx->c_ctx.uc_mgr = mgr_ctx; 2237961SNatalie.Li@Sun.COM 2247961SNatalie.Li@Sun.COM return (ndr_hdalloc(mxa, ctx)); 2257961SNatalie.Li@Sun.COM } 2267961SNatalie.Li@Sun.COM 2277961SNatalie.Li@Sun.COM /* 2287961SNatalie.Li@Sun.COM * svcctl_get_mgr_ctx 2297961SNatalie.Li@Sun.COM * 2307961SNatalie.Li@Sun.COM * This function looks up a reference to local manager context. 2317961SNatalie.Li@Sun.COM */ 2327961SNatalie.Li@Sun.COM static svcctl_manager_context_t * 2337961SNatalie.Li@Sun.COM svcctl_get_mgr_ctx(ndr_xa_t *mxa, ndr_hdid_t *mgr_id) 2347961SNatalie.Li@Sun.COM { 2357961SNatalie.Li@Sun.COM ndr_handle_t *hd; 2367961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 2377961SNatalie.Li@Sun.COM 2387961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, mgr_id, SVCCTL_MANAGER_CONTEXT); 2397961SNatalie.Li@Sun.COM if (hd == NULL) 2407961SNatalie.Li@Sun.COM return (NULL); 2417961SNatalie.Li@Sun.COM 2427961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 2437961SNatalie.Li@Sun.COM 2447961SNatalie.Li@Sun.COM return (mgr_ctx); 2457961SNatalie.Li@Sun.COM } 2467961SNatalie.Li@Sun.COM 2477961SNatalie.Li@Sun.COM /* 2487961SNatalie.Li@Sun.COM * svcctl_svc_hdalloc 2497961SNatalie.Li@Sun.COM * 2507961SNatalie.Li@Sun.COM * Handle allocation wrapper to setup the local service context. 2517961SNatalie.Li@Sun.COM */ 2527961SNatalie.Li@Sun.COM static ndr_hdid_t * 2537961SNatalie.Li@Sun.COM svcctl_svc_hdalloc(ndr_xa_t *mxa, ndr_hdid_t *mgr_id, char *svc_name) 2547961SNatalie.Li@Sun.COM { 2557961SNatalie.Li@Sun.COM svcctl_context_t *ctx; 2567961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 2577961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 2587961SNatalie.Li@Sun.COM int max_name_sz = 0; 2597961SNatalie.Li@Sun.COM char *svcname; 2607961SNatalie.Li@Sun.COM 2617961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, mgr_id); 2627961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) 2637961SNatalie.Li@Sun.COM return (NULL); 2647961SNatalie.Li@Sun.COM max_name_sz = mgr_ctx->mc_scf_max_fmri_len; 2657961SNatalie.Li@Sun.COM 2667961SNatalie.Li@Sun.COM if ((ctx = malloc(sizeof (svcctl_context_t))) == NULL) { 2677961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id); 2687961SNatalie.Li@Sun.COM return (NULL); 2697961SNatalie.Li@Sun.COM } 2707961SNatalie.Li@Sun.COM ctx->c_type = SVCCTL_SERVICE_CONTEXT; 2717961SNatalie.Li@Sun.COM 2727961SNatalie.Li@Sun.COM if ((svc_ctx = malloc(sizeof (svcctl_service_context_t))) == NULL) { 2737961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id); 2747961SNatalie.Li@Sun.COM free(ctx); 2757961SNatalie.Li@Sun.COM return (NULL); 2767961SNatalie.Li@Sun.COM } 2777961SNatalie.Li@Sun.COM bzero(svc_ctx, sizeof (svcctl_service_context_t)); 2787961SNatalie.Li@Sun.COM 2797961SNatalie.Li@Sun.COM svc_ctx->sc_mgrid = malloc(sizeof (ndr_hdid_t)); 2807961SNatalie.Li@Sun.COM svcname = malloc(max_name_sz); 2817961SNatalie.Li@Sun.COM 2827961SNatalie.Li@Sun.COM if ((svc_ctx->sc_mgrid == NULL) || (svcname == NULL)) { 2837961SNatalie.Li@Sun.COM free(svc_ctx->sc_mgrid); 2847961SNatalie.Li@Sun.COM free(svc_ctx); 2857961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id); 2867961SNatalie.Li@Sun.COM free(ctx); 2877961SNatalie.Li@Sun.COM return (NULL); 2887961SNatalie.Li@Sun.COM } 2897961SNatalie.Li@Sun.COM 2907961SNatalie.Li@Sun.COM svc_ctx->sc_svcname = svcname; 2917961SNatalie.Li@Sun.COM 2927961SNatalie.Li@Sun.COM bcopy(mgr_id, svc_ctx->sc_mgrid, sizeof (ndr_hdid_t)); 2937961SNatalie.Li@Sun.COM (void) strlcpy(svc_ctx->sc_svcname, svc_name, max_name_sz); 2947961SNatalie.Li@Sun.COM 2957961SNatalie.Li@Sun.COM ctx->c_ctx.uc_svc = svc_ctx; 2967961SNatalie.Li@Sun.COM 2977961SNatalie.Li@Sun.COM return (ndr_hdalloc(mxa, ctx)); 2987961SNatalie.Li@Sun.COM } 2997961SNatalie.Li@Sun.COM 3007961SNatalie.Li@Sun.COM /* 3017961SNatalie.Li@Sun.COM * svcctl_s_Close 3027961SNatalie.Li@Sun.COM * 3037961SNatalie.Li@Sun.COM * This is a request to close the SVCCTL interface specified by the 3047961SNatalie.Li@Sun.COM * handle. Free the handle and zero out the result handle for the 3057961SNatalie.Li@Sun.COM * client. 3067961SNatalie.Li@Sun.COM * 3077961SNatalie.Li@Sun.COM * Returns: 3087961SNatalie.Li@Sun.COM * ERROR_SUCCESS 3097961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 3107961SNatalie.Li@Sun.COM */ 3117961SNatalie.Li@Sun.COM static int 3128334SJose.Borrego@Sun.COM svcctl_s_Close(void *arg, ndr_xa_t *mxa) 3137961SNatalie.Li@Sun.COM { 3147961SNatalie.Li@Sun.COM struct svcctl_Close *param = arg; 3157961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 3167961SNatalie.Li@Sun.COM 3177961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, id); 3187961SNatalie.Li@Sun.COM 3197961SNatalie.Li@Sun.COM bzero(¶m->result_handle, sizeof (svcctl_handle_t)); 3207961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 3218334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 3227961SNatalie.Li@Sun.COM } 3237961SNatalie.Li@Sun.COM 3247961SNatalie.Li@Sun.COM /* 325*10001SJoyce.McIntosh@Sun.COM * svcctl_s_ControlService 326*10001SJoyce.McIntosh@Sun.COM */ 327*10001SJoyce.McIntosh@Sun.COM static int 328*10001SJoyce.McIntosh@Sun.COM svcctl_s_ControlService(void *arg, ndr_xa_t *mxa) 329*10001SJoyce.McIntosh@Sun.COM { 330*10001SJoyce.McIntosh@Sun.COM struct svcctl_ControlService *param = arg; 331*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 332*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 333*10001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 334*10001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx; 335*10001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc; 336*10001SJoyce.McIntosh@Sun.COM 337*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 338*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 339*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService)); 340*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 341*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 342*10001SJoyce.McIntosh@Sun.COM } 343*10001SJoyce.McIntosh@Sun.COM 344*10001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 345*10001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 346*10001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) { 347*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService)); 348*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 349*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 350*10001SJoyce.McIntosh@Sun.COM } 351*10001SJoyce.McIntosh@Sun.COM 352*10001SJoyce.McIntosh@Sun.COM switch (param->control) { 353*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_STOP: 354*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_PAUSE: 355*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_CONTINUE: 356*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_INTERROGATE: 357*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_SHUTDOWN: 358*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_PARAMCHANGE: 359*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDADD: 360*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDREMOVE: 361*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDENABLE: 362*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDDISABLE: 363*10001SJoyce.McIntosh@Sun.COM break; 364*10001SJoyce.McIntosh@Sun.COM default: 365*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService)); 366*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_PARAMETER; 367*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 368*10001SJoyce.McIntosh@Sun.COM } 369*10001SJoyce.McIntosh@Sun.COM 370*10001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 371*10001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) { 372*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService)); 373*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 374*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 375*10001SJoyce.McIntosh@Sun.COM } 376*10001SJoyce.McIntosh@Sun.COM 377*10001SJoyce.McIntosh@Sun.COM param->service_status.service_type = SERVICE_WIN32_SHARE_PROCESS; 378*10001SJoyce.McIntosh@Sun.COM param->service_status.cur_state = svcctl_scm_map_status(svc->sn_state); 379*10001SJoyce.McIntosh@Sun.COM param->service_status.ctrl_accepted = 0; 380*10001SJoyce.McIntosh@Sun.COM param->service_status.w32_exitcode = 0; 381*10001SJoyce.McIntosh@Sun.COM param->service_status.svc_specified_exitcode = 0; 382*10001SJoyce.McIntosh@Sun.COM param->service_status.check_point = 0; 383*10001SJoyce.McIntosh@Sun.COM param->service_status.wait_hint = 0; 384*10001SJoyce.McIntosh@Sun.COM 385*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 386*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 387*10001SJoyce.McIntosh@Sun.COM } 388*10001SJoyce.McIntosh@Sun.COM 389*10001SJoyce.McIntosh@Sun.COM /* 390*10001SJoyce.McIntosh@Sun.COM * svcctl_s_DeleteService 391*10001SJoyce.McIntosh@Sun.COM */ 392*10001SJoyce.McIntosh@Sun.COM static int 393*10001SJoyce.McIntosh@Sun.COM svcctl_s_DeleteService(void *arg, ndr_xa_t *mxa) 394*10001SJoyce.McIntosh@Sun.COM { 395*10001SJoyce.McIntosh@Sun.COM struct svcctl_DeleteService *param = arg; 396*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 397*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 398*10001SJoyce.McIntosh@Sun.COM 399*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 400*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 401*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 402*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 403*10001SJoyce.McIntosh@Sun.COM } 404*10001SJoyce.McIntosh@Sun.COM 405*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 406*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 407*10001SJoyce.McIntosh@Sun.COM } 408*10001SJoyce.McIntosh@Sun.COM 409*10001SJoyce.McIntosh@Sun.COM /* 410*10001SJoyce.McIntosh@Sun.COM * svcctl_s_QueryServiceSecurity 411*10001SJoyce.McIntosh@Sun.COM */ 412*10001SJoyce.McIntosh@Sun.COM static int 413*10001SJoyce.McIntosh@Sun.COM svcctl_s_QueryServiceSecurity(void *arg, ndr_xa_t *mxa) 414*10001SJoyce.McIntosh@Sun.COM { 415*10001SJoyce.McIntosh@Sun.COM struct svcctl_QueryServiceSecurity *param = arg; 416*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 417*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 418*10001SJoyce.McIntosh@Sun.COM uint32_t sec_info; 419*10001SJoyce.McIntosh@Sun.COM uint32_t bytes_needed = 0; 420*10001SJoyce.McIntosh@Sun.COM uint32_t status; 421*10001SJoyce.McIntosh@Sun.COM 422*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 423*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 424*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 425*10001SJoyce.McIntosh@Sun.COM goto query_service_security_error; 426*10001SJoyce.McIntosh@Sun.COM } 427*10001SJoyce.McIntosh@Sun.COM 428*10001SJoyce.McIntosh@Sun.COM sec_info = param->security_info & SMB_ALL_SECINFO; 429*10001SJoyce.McIntosh@Sun.COM if (sec_info == 0) { 430*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER; 431*10001SJoyce.McIntosh@Sun.COM goto query_service_security_error; 432*10001SJoyce.McIntosh@Sun.COM } 433*10001SJoyce.McIntosh@Sun.COM 434*10001SJoyce.McIntosh@Sun.COM if (param->buf_size < SVCCTL_SECURITY_BUFSIZE) { 435*10001SJoyce.McIntosh@Sun.COM bytes_needed = SVCCTL_SECURITY_BUFSIZE; 436*10001SJoyce.McIntosh@Sun.COM status = ERROR_INSUFFICIENT_BUFFER; 437*10001SJoyce.McIntosh@Sun.COM goto query_service_security_error; 438*10001SJoyce.McIntosh@Sun.COM } 439*10001SJoyce.McIntosh@Sun.COM 440*10001SJoyce.McIntosh@Sun.COM param->buffer = NDR_MALLOC(mxa, SVCCTL_SECURITY_BUFSIZE); 441*10001SJoyce.McIntosh@Sun.COM if (param->buffer == NULL) { 442*10001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 443*10001SJoyce.McIntosh@Sun.COM goto query_service_security_error; 444*10001SJoyce.McIntosh@Sun.COM } 445*10001SJoyce.McIntosh@Sun.COM 446*10001SJoyce.McIntosh@Sun.COM bzero(param->buffer, sizeof (SVCCTL_SECURITY_BUFSIZE)); 447*10001SJoyce.McIntosh@Sun.COM param->buf_size = SVCCTL_SECURITY_BUFSIZE; 448*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 449*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 450*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 451*10001SJoyce.McIntosh@Sun.COM 452*10001SJoyce.McIntosh@Sun.COM query_service_security_error: 453*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceSecurity)); 454*10001SJoyce.McIntosh@Sun.COM param->buf_size = 0; 455*10001SJoyce.McIntosh@Sun.COM param->buffer = NDR_MALLOC(mxa, sizeof (uint32_t)); 456*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = bytes_needed; 457*10001SJoyce.McIntosh@Sun.COM param->status = status; 458*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 459*10001SJoyce.McIntosh@Sun.COM } 460*10001SJoyce.McIntosh@Sun.COM 461*10001SJoyce.McIntosh@Sun.COM 462*10001SJoyce.McIntosh@Sun.COM /* 463*10001SJoyce.McIntosh@Sun.COM * svcctl_s_SetServiceSecurity 464*10001SJoyce.McIntosh@Sun.COM */ 465*10001SJoyce.McIntosh@Sun.COM static int 466*10001SJoyce.McIntosh@Sun.COM svcctl_s_SetServiceSecurity(void *arg, ndr_xa_t *mxa) 467*10001SJoyce.McIntosh@Sun.COM { 468*10001SJoyce.McIntosh@Sun.COM struct svcctl_SetServiceSecurity *param = arg; 469*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 470*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 471*10001SJoyce.McIntosh@Sun.COM 472*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 473*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 474*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 475*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 476*10001SJoyce.McIntosh@Sun.COM } 477*10001SJoyce.McIntosh@Sun.COM 478*10001SJoyce.McIntosh@Sun.COM if ((param->security_info & SMB_ALL_SECINFO) == 0) { 479*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_PARAMETER; 480*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 481*10001SJoyce.McIntosh@Sun.COM } 482*10001SJoyce.McIntosh@Sun.COM 483*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED; 484*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 485*10001SJoyce.McIntosh@Sun.COM } 486*10001SJoyce.McIntosh@Sun.COM 487*10001SJoyce.McIntosh@Sun.COM /* 4887961SNatalie.Li@Sun.COM * svcctl_s_OpenManager 4897961SNatalie.Li@Sun.COM * 4907961SNatalie.Li@Sun.COM * Request to open the service control manager. 4917961SNatalie.Li@Sun.COM * The caller must have administrator rights in order to open this 4927961SNatalie.Li@Sun.COM * interface. We don't support write (SC_MANAGER_LOCK) access. 4937961SNatalie.Li@Sun.COM * 4947961SNatalie.Li@Sun.COM * Returns: 4957961SNatalie.Li@Sun.COM * ERROR_SUCCESS 4967961SNatalie.Li@Sun.COM * ERROR_ACCESS_DENIED 4977961SNatalie.Li@Sun.COM * 4987961SNatalie.Li@Sun.COM * On success, returns a handle for use with subsequent svcctl requests. 4997961SNatalie.Li@Sun.COM */ 5007961SNatalie.Li@Sun.COM static int 5018334SJose.Borrego@Sun.COM svcctl_s_OpenManager(void *arg, ndr_xa_t *mxa) 5027961SNatalie.Li@Sun.COM { 5037961SNatalie.Li@Sun.COM struct svcctl_OpenManager *param = arg; 5047961SNatalie.Li@Sun.COM ndr_hdid_t *id = NULL; 5057961SNatalie.Li@Sun.COM int rc; 5067961SNatalie.Li@Sun.COM 5077961SNatalie.Li@Sun.COM rc = ndr_is_admin(mxa); 5087961SNatalie.Li@Sun.COM 5097961SNatalie.Li@Sun.COM if ((rc == 0) || (param->desired_access & SC_MANAGER_LOCK) != 0) { 5107961SNatalie.Li@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t)); 5117961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED; 5128334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5137961SNatalie.Li@Sun.COM } 5147961SNatalie.Li@Sun.COM 5157961SNatalie.Li@Sun.COM id = svcctl_mgr_hdalloc(mxa); 5167961SNatalie.Li@Sun.COM if (id) { 5177961SNatalie.Li@Sun.COM bcopy(id, ¶m->handle, sizeof (svcctl_handle_t)); 5187961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 5197961SNatalie.Li@Sun.COM } else { 5207961SNatalie.Li@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t)); 5217961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED; 5227961SNatalie.Li@Sun.COM } 5237961SNatalie.Li@Sun.COM 5248334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5257961SNatalie.Li@Sun.COM } 5267961SNatalie.Li@Sun.COM 5277961SNatalie.Li@Sun.COM /* 5287961SNatalie.Li@Sun.COM * svcctl_s_OpenService 5297961SNatalie.Li@Sun.COM * 5307961SNatalie.Li@Sun.COM * Return a handle for use with subsequent svcctl requests. 5317961SNatalie.Li@Sun.COM * 5327961SNatalie.Li@Sun.COM * Returns: 5337961SNatalie.Li@Sun.COM * ERROR_SUCCESS 5347961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 5357961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST 5367961SNatalie.Li@Sun.COM * ERROR_CALL_NOT_IMPLEMENTED 5377961SNatalie.Li@Sun.COM */ 5387961SNatalie.Li@Sun.COM static int 5398334SJose.Borrego@Sun.COM svcctl_s_OpenService(void *arg, ndr_xa_t *mxa) 5407961SNatalie.Li@Sun.COM { 5417961SNatalie.Li@Sun.COM struct svcctl_OpenService *param = arg; 5427961SNatalie.Li@Sun.COM ndr_hdid_t *mgrid = (ndr_hdid_t *)¶m->manager_handle; 5437961SNatalie.Li@Sun.COM ndr_hdid_t *id = NULL; 5447961SNatalie.Li@Sun.COM ndr_handle_t *hd; 5457961SNatalie.Li@Sun.COM DWORD status; 5467961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 5477961SNatalie.Li@Sun.COM char *svc_name = (char *)param->service_name; 5487961SNatalie.Li@Sun.COM boolean_t unimplemented_operations = B_FALSE; 5497961SNatalie.Li@Sun.COM 5507961SNatalie.Li@Sun.COM /* Allow service handle allocations for only status & config queries */ 5517961SNatalie.Li@Sun.COM unimplemented_operations = 5527961SNatalie.Li@Sun.COM SVCCTL_OPENSVC_OP_UNIMPLEMENTED(param->desired_access); 5537961SNatalie.Li@Sun.COM 5547961SNatalie.Li@Sun.COM if (unimplemented_operations) { 5557961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 5567961SNatalie.Li@Sun.COM param->status = ERROR_CALL_NOT_IMPLEMENTED; 5578334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5587961SNatalie.Li@Sun.COM } 5597961SNatalie.Li@Sun.COM 5607961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, mgrid, SVCCTL_MANAGER_CONTEXT); 5617961SNatalie.Li@Sun.COM if (hd == NULL) { 5627961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 5637961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 5648334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5657961SNatalie.Li@Sun.COM } 5667961SNatalie.Li@Sun.COM 5677961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 5687961SNatalie.Li@Sun.COM status = svcctl_scm_validate_service(mgr_ctx, svc_name); 5697961SNatalie.Li@Sun.COM if (status != ERROR_SUCCESS) { 5707961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 5717961SNatalie.Li@Sun.COM param->status = status; 5728334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5737961SNatalie.Li@Sun.COM } 5747961SNatalie.Li@Sun.COM 5757961SNatalie.Li@Sun.COM id = svcctl_svc_hdalloc(mxa, mgrid, svc_name); 5767961SNatalie.Li@Sun.COM if (id) { 5777961SNatalie.Li@Sun.COM bcopy(id, ¶m->service_handle, sizeof (svcctl_handle_t)); 5787961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 5797961SNatalie.Li@Sun.COM } else { 5807961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 5817961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED; 5827961SNatalie.Li@Sun.COM } 5837961SNatalie.Li@Sun.COM 5848334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5857961SNatalie.Li@Sun.COM } 5867961SNatalie.Li@Sun.COM 5877961SNatalie.Li@Sun.COM /* 5887961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceStatus 5897961SNatalie.Li@Sun.COM * 5907961SNatalie.Li@Sun.COM * Returns: 5917961SNatalie.Li@Sun.COM * ERROR_SUCCESS 5927961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 5937961SNatalie.Li@Sun.COM */ 5947961SNatalie.Li@Sun.COM static int 5958334SJose.Borrego@Sun.COM svcctl_s_QueryServiceStatus(void *arg, ndr_xa_t *mxa) 5967961SNatalie.Li@Sun.COM { 5977961SNatalie.Li@Sun.COM struct svcctl_QueryServiceStatus *param = arg; 5987961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 5997961SNatalie.Li@Sun.COM ndr_handle_t *hd; 6007961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 6017961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 6027961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 6037961SNatalie.Li@Sun.COM 6047961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 6057961SNatalie.Li@Sun.COM if (hd == NULL) { 6067961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus)); 6077961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 6088334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6097961SNatalie.Li@Sun.COM } 6107961SNatalie.Li@Sun.COM 6117961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 6127961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 6137961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) { 614*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus)); 6157961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 6168334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6177961SNatalie.Li@Sun.COM } 6187961SNatalie.Li@Sun.COM 6197961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 6207961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_state == NULL) { 621*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus)); 6227961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 6238334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6247961SNatalie.Li@Sun.COM } 6257961SNatalie.Li@Sun.COM 6267961SNatalie.Li@Sun.COM param->service_status.service_type = SERVICE_WIN32_SHARE_PROCESS; 6277961SNatalie.Li@Sun.COM param->service_status.cur_state = svcctl_scm_map_status(svc->sn_state); 6287961SNatalie.Li@Sun.COM param->service_status.ctrl_accepted = 0; 6297961SNatalie.Li@Sun.COM param->service_status.w32_exitcode = 0; 6307961SNatalie.Li@Sun.COM param->service_status.svc_specified_exitcode = 0; 6317961SNatalie.Li@Sun.COM param->service_status.check_point = 0; 6327961SNatalie.Li@Sun.COM param->service_status.wait_hint = 0; 6337961SNatalie.Li@Sun.COM 6347961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 6358334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6367961SNatalie.Li@Sun.COM } 6377961SNatalie.Li@Sun.COM 6387961SNatalie.Li@Sun.COM /* 639*10001SJoyce.McIntosh@Sun.COM * svcctl_s_EnumDependentServices 640*10001SJoyce.McIntosh@Sun.COM * 641*10001SJoyce.McIntosh@Sun.COM * Enumerate the list of services that depend on the specified service. 642*10001SJoyce.McIntosh@Sun.COM */ 643*10001SJoyce.McIntosh@Sun.COM static int 644*10001SJoyce.McIntosh@Sun.COM svcctl_s_EnumDependentServices(void *arg, ndr_xa_t *mxa) 645*10001SJoyce.McIntosh@Sun.COM { 646*10001SJoyce.McIntosh@Sun.COM struct svcctl_EnumDependentServices *param = arg; 647*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 648*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 649*10001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 650*10001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx; 651*10001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc; 652*10001SJoyce.McIntosh@Sun.COM int input_bufsize = 0; 653*10001SJoyce.McIntosh@Sun.COM uint32_t status; 654*10001SJoyce.McIntosh@Sun.COM 655*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 656*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 657*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 658*10001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 659*10001SJoyce.McIntosh@Sun.COM } 660*10001SJoyce.McIntosh@Sun.COM 661*10001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 662*10001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 663*10001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) { 664*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 665*10001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 666*10001SJoyce.McIntosh@Sun.COM } 667*10001SJoyce.McIntosh@Sun.COM 668*10001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 669*10001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) { 670*10001SJoyce.McIntosh@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST; 671*10001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 672*10001SJoyce.McIntosh@Sun.COM } 673*10001SJoyce.McIntosh@Sun.COM 674*10001SJoyce.McIntosh@Sun.COM switch (param->svc_state) { 675*10001SJoyce.McIntosh@Sun.COM case SERVICE_STOPPED: 676*10001SJoyce.McIntosh@Sun.COM case SERVICE_START_PENDING: 677*10001SJoyce.McIntosh@Sun.COM case SERVICE_STOP_PENDING: 678*10001SJoyce.McIntosh@Sun.COM case SERVICE_RUNNING: 679*10001SJoyce.McIntosh@Sun.COM case SERVICE_CONTINUE_PENDING: 680*10001SJoyce.McIntosh@Sun.COM case SERVICE_PAUSE_PENDING: 681*10001SJoyce.McIntosh@Sun.COM case SERVICE_PAUSED: 682*10001SJoyce.McIntosh@Sun.COM break; 683*10001SJoyce.McIntosh@Sun.COM default: 684*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER; 685*10001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 686*10001SJoyce.McIntosh@Sun.COM } 687*10001SJoyce.McIntosh@Sun.COM 688*10001SJoyce.McIntosh@Sun.COM if ((input_bufsize = param->buf_size) == 0) { 689*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumDependentServices)); 690*10001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize; 691*10001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, ""); 692*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = 1024; 693*10001SJoyce.McIntosh@Sun.COM param->svc_num = 0; 694*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA; 695*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 696*10001SJoyce.McIntosh@Sun.COM } 697*10001SJoyce.McIntosh@Sun.COM 698*10001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, input_bufsize); 699*10001SJoyce.McIntosh@Sun.COM if (param->services == NULL) { 700*10001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 701*10001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 702*10001SJoyce.McIntosh@Sun.COM } 703*10001SJoyce.McIntosh@Sun.COM 704*10001SJoyce.McIntosh@Sun.COM bzero(param->services, input_bufsize); 705*10001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize; 706*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 707*10001SJoyce.McIntosh@Sun.COM param->svc_num = 0; 708*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 709*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 710*10001SJoyce.McIntosh@Sun.COM 711*10001SJoyce.McIntosh@Sun.COM enum_dependent_services_error: 712*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumDependentServices)); 713*10001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, ""); 714*10001SJoyce.McIntosh@Sun.COM param->status = status; 715*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 716*10001SJoyce.McIntosh@Sun.COM } 717*10001SJoyce.McIntosh@Sun.COM 718*10001SJoyce.McIntosh@Sun.COM /* 7197961SNatalie.Li@Sun.COM * svcctl_s_EnumServicesStatus 7207961SNatalie.Li@Sun.COM * 721*10001SJoyce.McIntosh@Sun.COM * Enumerate the list of services we support. 7227961SNatalie.Li@Sun.COM */ 7237961SNatalie.Li@Sun.COM static int 7248334SJose.Borrego@Sun.COM svcctl_s_EnumServicesStatus(void *arg, ndr_xa_t *mxa) 7257961SNatalie.Li@Sun.COM { 7267961SNatalie.Li@Sun.COM struct svcctl_EnumServicesStatus *param = arg; 7277961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; 7287961SNatalie.Li@Sun.COM ndr_handle_t *hd; 7297961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 730*10001SJoyce.McIntosh@Sun.COM uint32_t buf_size = 0; 731*10001SJoyce.McIntosh@Sun.COM uint32_t svc_num; 732*10001SJoyce.McIntosh@Sun.COM uint32_t resume_handle = 0; 733*10001SJoyce.McIntosh@Sun.COM uint32_t status; 734*10001SJoyce.McIntosh@Sun.COM 735*10001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL) 736*10001SJoyce.McIntosh@Sun.COM resume_handle = *param->resume_handle; 7377961SNatalie.Li@Sun.COM 7387961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); 7397961SNatalie.Li@Sun.COM if (hd == NULL) { 740*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 741*10001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 7427961SNatalie.Li@Sun.COM } 7437961SNatalie.Li@Sun.COM 7447961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 7457961SNatalie.Li@Sun.COM if (svcctl_scm_refresh(mgr_ctx) != 0) { 746*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 747*10001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 7487961SNatalie.Li@Sun.COM } 7497961SNatalie.Li@Sun.COM 750*10001SJoyce.McIntosh@Sun.COM buf_size = param->buf_size; 751*10001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, buf_size); 7527961SNatalie.Li@Sun.COM if (param->services == NULL) { 753*10001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 754*10001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 7557961SNatalie.Li@Sun.COM } 756*10001SJoyce.McIntosh@Sun.COM bzero(param->services, buf_size); 7577961SNatalie.Li@Sun.COM 758*10001SJoyce.McIntosh@Sun.COM if (buf_size < SVCCTL_ENUMSERVICES_MINBUFSIZE) { 7597961SNatalie.Li@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed; 7607961SNatalie.Li@Sun.COM param->svc_num = 0; 761*10001SJoyce.McIntosh@Sun.COM if (param->resume_handle) 762*10001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0; 7637961SNatalie.Li@Sun.COM param->status = ERROR_MORE_DATA; 7648334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7657961SNatalie.Li@Sun.COM } 7667961SNatalie.Li@Sun.COM 767*10001SJoyce.McIntosh@Sun.COM svc_num = svcctl_scm_enum_services(mgr_ctx, param->services, 768*10001SJoyce.McIntosh@Sun.COM buf_size, &resume_handle, B_TRUE); 769*10001SJoyce.McIntosh@Sun.COM 770*10001SJoyce.McIntosh@Sun.COM param->buf_size = buf_size; 771*10001SJoyce.McIntosh@Sun.COM param->svc_num = svc_num; 7727961SNatalie.Li@Sun.COM 773*10001SJoyce.McIntosh@Sun.COM if (resume_handle != 0) { 774*10001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL) 775*10001SJoyce.McIntosh@Sun.COM *param->resume_handle = resume_handle; 776*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed; 777*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA; 778*10001SJoyce.McIntosh@Sun.COM } else { 779*10001SJoyce.McIntosh@Sun.COM if (param->resume_handle) 780*10001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0; 781*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 782*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 783*10001SJoyce.McIntosh@Sun.COM } 784*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 785*10001SJoyce.McIntosh@Sun.COM 786*10001SJoyce.McIntosh@Sun.COM enum_services_status_error: 787*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumServicesStatus)); 788*10001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, ""); 789*10001SJoyce.McIntosh@Sun.COM param->status = status; 7908334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7917961SNatalie.Li@Sun.COM } 7927961SNatalie.Li@Sun.COM 7937961SNatalie.Li@Sun.COM /* 7947961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceConfig 7957961SNatalie.Li@Sun.COM * 7967961SNatalie.Li@Sun.COM * Returns: 7977961SNatalie.Li@Sun.COM * ERROR_SUCCESS 7987961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 7997961SNatalie.Li@Sun.COM */ 8007961SNatalie.Li@Sun.COM static int 8018334SJose.Borrego@Sun.COM svcctl_s_QueryServiceConfig(void *arg, ndr_xa_t *mxa) 8027961SNatalie.Li@Sun.COM { 8037961SNatalie.Li@Sun.COM struct svcctl_QueryServiceConfig *param = arg; 8047961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 8057961SNatalie.Li@Sun.COM ndr_handle_t *hd; 8067961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 8077961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 8087961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 8097961SNatalie.Li@Sun.COM int bytes_needed = 0; 8107961SNatalie.Li@Sun.COM svc_config_t *cfg; 8117961SNatalie.Li@Sun.COM 8127961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 8137961SNatalie.Li@Sun.COM if (hd == NULL) { 8147961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig)); 8157961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 8168334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8177961SNatalie.Li@Sun.COM } 8187961SNatalie.Li@Sun.COM 8197961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 8207961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 8217961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) { 8227961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig)); 8237961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 8248334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8257961SNatalie.Li@Sun.COM } 8267961SNatalie.Li@Sun.COM 8277961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 8287961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_fmri == NULL) { 8297961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig)); 8307961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 8318334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8327961SNatalie.Li@Sun.COM } 8337961SNatalie.Li@Sun.COM 8347961SNatalie.Li@Sun.COM cfg = ¶m->service_cfg; 8357961SNatalie.Li@Sun.COM cfg->service_type = SERVICE_WIN32_SHARE_PROCESS; 8367961SNatalie.Li@Sun.COM cfg->start_type = SERVICE_AUTO_START; 8377961SNatalie.Li@Sun.COM cfg->error_control = SERVICE_AUTO_START; 8388334SJose.Borrego@Sun.COM cfg->binary_pathname = NDR_STRDUP(mxa, ""); 8398334SJose.Borrego@Sun.COM cfg->loadorder_group = NDR_STRDUP(mxa, ""); 8407961SNatalie.Li@Sun.COM cfg->tag_id = 0; 8418334SJose.Borrego@Sun.COM cfg->dependencies = NDR_STRDUP(mxa, ""); 8428334SJose.Borrego@Sun.COM cfg->service_startname = NDR_STRDUP(mxa, ""); 8438334SJose.Borrego@Sun.COM cfg->display_name = NDR_STRDUP(mxa, svc->sn_fmri); 8447961SNatalie.Li@Sun.COM 8457961SNatalie.Li@Sun.COM bytes_needed = sizeof (svc_config_t); 8467961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->binary_pathname); 8477961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->loadorder_group); 8487961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->dependencies); 8497961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->service_startname); 8507961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN(svc->sn_fmri); 8517961SNatalie.Li@Sun.COM 8527961SNatalie.Li@Sun.COM if (param->buf_size < bytes_needed) { 8537961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig)); 8547961SNatalie.Li@Sun.COM param->cfg_bytes = bytes_needed; 855*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER; 8568334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8577961SNatalie.Li@Sun.COM } 8587961SNatalie.Li@Sun.COM 8597961SNatalie.Li@Sun.COM param->cfg_bytes = bytes_needed; 8607961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 8618334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8627961SNatalie.Li@Sun.COM } 8637961SNatalie.Li@Sun.COM 8647961SNatalie.Li@Sun.COM /* 865*10001SJoyce.McIntosh@Sun.COM * svcctl_s_StartService 866*10001SJoyce.McIntosh@Sun.COM */ 867*10001SJoyce.McIntosh@Sun.COM static int 868*10001SJoyce.McIntosh@Sun.COM svcctl_s_StartService(void *arg, ndr_xa_t *mxa) 869*10001SJoyce.McIntosh@Sun.COM { 870*10001SJoyce.McIntosh@Sun.COM struct svcctl_StartService *param = arg; 871*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 872*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 873*10001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 874*10001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx; 875*10001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc; 876*10001SJoyce.McIntosh@Sun.COM 877*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 878*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 879*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 880*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 881*10001SJoyce.McIntosh@Sun.COM } 882*10001SJoyce.McIntosh@Sun.COM 883*10001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 884*10001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 885*10001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) { 886*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 887*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 888*10001SJoyce.McIntosh@Sun.COM } 889*10001SJoyce.McIntosh@Sun.COM 890*10001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 891*10001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_fmri == NULL) 892*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 893*10001SJoyce.McIntosh@Sun.COM else 894*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_ALREADY_RUNNING; 895*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 896*10001SJoyce.McIntosh@Sun.COM } 897*10001SJoyce.McIntosh@Sun.COM 898*10001SJoyce.McIntosh@Sun.COM 899*10001SJoyce.McIntosh@Sun.COM /* 9007961SNatalie.Li@Sun.COM * svcctl_s_GetServiceDisplayNameW 9017961SNatalie.Li@Sun.COM * 9027961SNatalie.Li@Sun.COM * Returns: 9037961SNatalie.Li@Sun.COM * ERROR_SUCCESS 9047961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 9057961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST 9067961SNatalie.Li@Sun.COM */ 9077961SNatalie.Li@Sun.COM static int 9088334SJose.Borrego@Sun.COM svcctl_s_GetServiceDisplayNameW(void *arg, ndr_xa_t *mxa) 9097961SNatalie.Li@Sun.COM { 9107961SNatalie.Li@Sun.COM struct svcctl_GetServiceDisplayNameW *param = arg; 9117961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; 9127961SNatalie.Li@Sun.COM ndr_handle_t *hd; 9137961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 9147961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 9157961SNatalie.Li@Sun.COM 9167961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); 9177961SNatalie.Li@Sun.COM if (hd == NULL) { 9187961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); 9198334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, ""); 9207961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 9218334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9227961SNatalie.Li@Sun.COM } 9237961SNatalie.Li@Sun.COM 9247961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 9257961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, (char *)param->service_name); 9267961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_fmri == NULL) { 9277961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); 9288334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, ""); 9297961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 9308334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9317961SNatalie.Li@Sun.COM } 9327961SNatalie.Li@Sun.COM 9338334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, svc->sn_fmri); 9347961SNatalie.Li@Sun.COM if (param->display_name == NULL) { 9357961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); 9368334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, ""); 9377961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 9388334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9397961SNatalie.Li@Sun.COM } 9407961SNatalie.Li@Sun.COM 9417961SNatalie.Li@Sun.COM param->buf_size = strlen(svc->sn_fmri); 9427961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 9438334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9447961SNatalie.Li@Sun.COM } 9457961SNatalie.Li@Sun.COM 9467961SNatalie.Li@Sun.COM /* 9477961SNatalie.Li@Sun.COM * svcctl_s_GetServiceKeyNameW 9487961SNatalie.Li@Sun.COM * 9497961SNatalie.Li@Sun.COM * Returns: 9507961SNatalie.Li@Sun.COM * ERROR_SUCCESS 9517961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 9527961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST 9537961SNatalie.Li@Sun.COM */ 9547961SNatalie.Li@Sun.COM static int 9558334SJose.Borrego@Sun.COM svcctl_s_GetServiceKeyNameW(void *arg, ndr_xa_t *mxa) 9567961SNatalie.Li@Sun.COM { 9577961SNatalie.Li@Sun.COM struct svcctl_GetServiceKeyNameW *param = arg; 9587961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; 9597961SNatalie.Li@Sun.COM ndr_handle_t *hd; 9607961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 9617961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 9627961SNatalie.Li@Sun.COM 9637961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); 9647961SNatalie.Li@Sun.COM if (hd == NULL) { 9657961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); 9668334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, ""); 9677961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 9688334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9697961SNatalie.Li@Sun.COM } 9707961SNatalie.Li@Sun.COM 9717961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 9727961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, (char *)param->service_name); 9737961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_name == NULL) { 9747961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); 9758334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, ""); 9767961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 9778334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9787961SNatalie.Li@Sun.COM } 9797961SNatalie.Li@Sun.COM 9808334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, svc->sn_name); 9817961SNatalie.Li@Sun.COM if (param->key_name == NULL) { 9827961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); 9838334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, ""); 9847961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 9858334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9867961SNatalie.Li@Sun.COM } 9877961SNatalie.Li@Sun.COM 9887961SNatalie.Li@Sun.COM param->buf_size = strlen(svc->sn_name); 9897961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 9908334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9917961SNatalie.Li@Sun.COM } 9927961SNatalie.Li@Sun.COM 9937961SNatalie.Li@Sun.COM /* 994*10001SJoyce.McIntosh@Sun.COM * svcctl_s_OpenSCManagerA 995*10001SJoyce.McIntosh@Sun.COM * 996*10001SJoyce.McIntosh@Sun.COM * Request to open the service control manager. 997*10001SJoyce.McIntosh@Sun.COM * The caller must have administrator rights in order to open this 998*10001SJoyce.McIntosh@Sun.COM * interface. We don't support write (SC_MANAGER_LOCK) access. 999*10001SJoyce.McIntosh@Sun.COM * 1000*10001SJoyce.McIntosh@Sun.COM * Returns: 1001*10001SJoyce.McIntosh@Sun.COM * ERROR_SUCCESS 1002*10001SJoyce.McIntosh@Sun.COM * ERROR_ACCESS_DENIED 1003*10001SJoyce.McIntosh@Sun.COM * 1004*10001SJoyce.McIntosh@Sun.COM * On success, returns a handle for use with subsequent svcctl requests. 1005*10001SJoyce.McIntosh@Sun.COM */ 1006*10001SJoyce.McIntosh@Sun.COM static int 1007*10001SJoyce.McIntosh@Sun.COM svcctl_s_OpenSCManagerA(void *arg, ndr_xa_t *mxa) 1008*10001SJoyce.McIntosh@Sun.COM { 1009*10001SJoyce.McIntosh@Sun.COM struct svcctl_OpenSCManagerA *param = arg; 1010*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = NULL; 1011*10001SJoyce.McIntosh@Sun.COM int rc; 1012*10001SJoyce.McIntosh@Sun.COM 1013*10001SJoyce.McIntosh@Sun.COM rc = ndr_is_admin(mxa); 1014*10001SJoyce.McIntosh@Sun.COM 1015*10001SJoyce.McIntosh@Sun.COM if ((rc == 0) || (param->desired_access & SC_MANAGER_LOCK) != 0) { 1016*10001SJoyce.McIntosh@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t)); 1017*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED; 1018*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1019*10001SJoyce.McIntosh@Sun.COM } 1020*10001SJoyce.McIntosh@Sun.COM 1021*10001SJoyce.McIntosh@Sun.COM id = svcctl_mgr_hdalloc(mxa); 1022*10001SJoyce.McIntosh@Sun.COM if (id) { 1023*10001SJoyce.McIntosh@Sun.COM bcopy(id, ¶m->handle, sizeof (svcctl_handle_t)); 1024*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 1025*10001SJoyce.McIntosh@Sun.COM } else { 1026*10001SJoyce.McIntosh@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t)); 1027*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED; 1028*10001SJoyce.McIntosh@Sun.COM } 1029*10001SJoyce.McIntosh@Sun.COM 1030*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1031*10001SJoyce.McIntosh@Sun.COM } 1032*10001SJoyce.McIntosh@Sun.COM 1033*10001SJoyce.McIntosh@Sun.COM /* 1034*10001SJoyce.McIntosh@Sun.COM * svcctl_s_OpenServiceA 1035*10001SJoyce.McIntosh@Sun.COM * 1036*10001SJoyce.McIntosh@Sun.COM * Return a handle for use with subsequent svcctl requests. 1037*10001SJoyce.McIntosh@Sun.COM * 1038*10001SJoyce.McIntosh@Sun.COM * Returns: 1039*10001SJoyce.McIntosh@Sun.COM * ERROR_SUCCESS 1040*10001SJoyce.McIntosh@Sun.COM * ERROR_INVALID_HANDLE 1041*10001SJoyce.McIntosh@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST 1042*10001SJoyce.McIntosh@Sun.COM * ERROR_CALL_NOT_IMPLEMENTED 1043*10001SJoyce.McIntosh@Sun.COM */ 1044*10001SJoyce.McIntosh@Sun.COM static int 1045*10001SJoyce.McIntosh@Sun.COM svcctl_s_OpenServiceA(void *arg, ndr_xa_t *mxa) 1046*10001SJoyce.McIntosh@Sun.COM { 1047*10001SJoyce.McIntosh@Sun.COM struct svcctl_OpenServiceA *param = arg; 1048*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *mgrid = (ndr_hdid_t *)¶m->manager_handle; 1049*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = NULL; 1050*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 1051*10001SJoyce.McIntosh@Sun.COM DWORD status; 1052*10001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 1053*10001SJoyce.McIntosh@Sun.COM char *svc_name = (char *)param->service_name->value; 1054*10001SJoyce.McIntosh@Sun.COM boolean_t unimplemented_operations = B_FALSE; 1055*10001SJoyce.McIntosh@Sun.COM 1056*10001SJoyce.McIntosh@Sun.COM /* Allow service handle allocations for only status & config queries */ 1057*10001SJoyce.McIntosh@Sun.COM unimplemented_operations = 1058*10001SJoyce.McIntosh@Sun.COM SVCCTL_OPENSVC_OP_UNIMPLEMENTED(param->desired_access); 1059*10001SJoyce.McIntosh@Sun.COM 1060*10001SJoyce.McIntosh@Sun.COM if (unimplemented_operations) { 1061*10001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 1062*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_CALL_NOT_IMPLEMENTED; 1063*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1064*10001SJoyce.McIntosh@Sun.COM } 1065*10001SJoyce.McIntosh@Sun.COM 1066*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, mgrid, SVCCTL_MANAGER_CONTEXT); 1067*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 1068*10001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 1069*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 1070*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1071*10001SJoyce.McIntosh@Sun.COM } 1072*10001SJoyce.McIntosh@Sun.COM 1073*10001SJoyce.McIntosh@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 1074*10001SJoyce.McIntosh@Sun.COM status = svcctl_scm_validate_service(mgr_ctx, svc_name); 1075*10001SJoyce.McIntosh@Sun.COM if (status != ERROR_SUCCESS) { 1076*10001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 1077*10001SJoyce.McIntosh@Sun.COM param->status = status; 1078*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1079*10001SJoyce.McIntosh@Sun.COM } 1080*10001SJoyce.McIntosh@Sun.COM 1081*10001SJoyce.McIntosh@Sun.COM id = svcctl_svc_hdalloc(mxa, mgrid, svc_name); 1082*10001SJoyce.McIntosh@Sun.COM if (id) { 1083*10001SJoyce.McIntosh@Sun.COM bcopy(id, ¶m->service_handle, sizeof (svcctl_handle_t)); 1084*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 1085*10001SJoyce.McIntosh@Sun.COM } else { 1086*10001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 1087*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED; 1088*10001SJoyce.McIntosh@Sun.COM } 1089*10001SJoyce.McIntosh@Sun.COM 1090*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1091*10001SJoyce.McIntosh@Sun.COM } 1092*10001SJoyce.McIntosh@Sun.COM 1093*10001SJoyce.McIntosh@Sun.COM /* 1094*10001SJoyce.McIntosh@Sun.COM * svcctl_s_EnumServicesStatusA 1095*10001SJoyce.McIntosh@Sun.COM * 1096*10001SJoyce.McIntosh@Sun.COM * Enumerate the list of services we support as ASCII. 1097*10001SJoyce.McIntosh@Sun.COM */ 1098*10001SJoyce.McIntosh@Sun.COM static int 1099*10001SJoyce.McIntosh@Sun.COM svcctl_s_EnumServicesStatusA(void *arg, ndr_xa_t *mxa) 1100*10001SJoyce.McIntosh@Sun.COM { 1101*10001SJoyce.McIntosh@Sun.COM struct svcctl_EnumServicesStatusA *param = arg; 1102*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; 1103*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 1104*10001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 1105*10001SJoyce.McIntosh@Sun.COM uint32_t buf_size; 1106*10001SJoyce.McIntosh@Sun.COM uint32_t svc_num; 1107*10001SJoyce.McIntosh@Sun.COM uint32_t resume_handle = 0; 1108*10001SJoyce.McIntosh@Sun.COM uint32_t status; 1109*10001SJoyce.McIntosh@Sun.COM 1110*10001SJoyce.McIntosh@Sun.COM buf_size = param->buf_size; 1111*10001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL) 1112*10001SJoyce.McIntosh@Sun.COM resume_handle = *param->resume_handle; 1113*10001SJoyce.McIntosh@Sun.COM 1114*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); 1115*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 1116*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 1117*10001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 1118*10001SJoyce.McIntosh@Sun.COM } 1119*10001SJoyce.McIntosh@Sun.COM 1120*10001SJoyce.McIntosh@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 1121*10001SJoyce.McIntosh@Sun.COM if (svcctl_scm_refresh(mgr_ctx) != 0) { 1122*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 1123*10001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 1124*10001SJoyce.McIntosh@Sun.COM } 1125*10001SJoyce.McIntosh@Sun.COM 1126*10001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, buf_size); 1127*10001SJoyce.McIntosh@Sun.COM if (param->services == NULL) { 1128*10001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 1129*10001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 1130*10001SJoyce.McIntosh@Sun.COM } 1131*10001SJoyce.McIntosh@Sun.COM bzero(param->services, buf_size); 1132*10001SJoyce.McIntosh@Sun.COM 1133*10001SJoyce.McIntosh@Sun.COM svc_num = svcctl_scm_enum_services(mgr_ctx, param->services, 1134*10001SJoyce.McIntosh@Sun.COM buf_size, &resume_handle, B_FALSE); 1135*10001SJoyce.McIntosh@Sun.COM 1136*10001SJoyce.McIntosh@Sun.COM param->buf_size = buf_size; 1137*10001SJoyce.McIntosh@Sun.COM param->svc_num = svc_num; 1138*10001SJoyce.McIntosh@Sun.COM 1139*10001SJoyce.McIntosh@Sun.COM if (resume_handle != 0) { 1140*10001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL) 1141*10001SJoyce.McIntosh@Sun.COM *param->resume_handle = resume_handle; 1142*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed; 1143*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA; 1144*10001SJoyce.McIntosh@Sun.COM } else { 1145*10001SJoyce.McIntosh@Sun.COM if (param->resume_handle) 1146*10001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0; 1147*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 1148*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 1149*10001SJoyce.McIntosh@Sun.COM } 1150*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1151*10001SJoyce.McIntosh@Sun.COM 1152*10001SJoyce.McIntosh@Sun.COM enum_services_status_error: 1153*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumServicesStatusA)); 1154*10001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, ""); 1155*10001SJoyce.McIntosh@Sun.COM param->status = status; 1156*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1157*10001SJoyce.McIntosh@Sun.COM } 1158*10001SJoyce.McIntosh@Sun.COM 1159*10001SJoyce.McIntosh@Sun.COM /* 11607961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceConfig2W 11617961SNatalie.Li@Sun.COM * 11627961SNatalie.Li@Sun.COM * Returns: 11637961SNatalie.Li@Sun.COM * ERROR_SUCCESS 11647961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 11657961SNatalie.Li@Sun.COM * ERROR_INVALID_LEVEL 11667961SNatalie.Li@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 11677961SNatalie.Li@Sun.COM */ 11687961SNatalie.Li@Sun.COM static int 11698334SJose.Borrego@Sun.COM svcctl_s_QueryServiceConfig2W(void *arg, ndr_xa_t *mxa) 11707961SNatalie.Li@Sun.COM { 11717961SNatalie.Li@Sun.COM struct svcctl_QueryServiceConfig2W *param = arg; 11727961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 11737961SNatalie.Li@Sun.COM ndr_handle_t *hd; 11747961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 11757961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 11767961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 11777961SNatalie.Li@Sun.COM svc_description_t *svc_desc; 11787961SNatalie.Li@Sun.COM svc_failure_actions_t *fac; 11797961SNatalie.Li@Sun.COM int offset, input_bufsize, bytes_needed = 0; 11807961SNatalie.Li@Sun.COM mts_wchar_t *wide_desc; 11817961SNatalie.Li@Sun.COM char *desc; 11827961SNatalie.Li@Sun.COM DWORD status; 11837961SNatalie.Li@Sun.COM 11847961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 11857961SNatalie.Li@Sun.COM if (hd == NULL) { 11867961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); 11878334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 11887961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 11898334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 11907961SNatalie.Li@Sun.COM } 11917961SNatalie.Li@Sun.COM 11927961SNatalie.Li@Sun.COM input_bufsize = param->buf_size; 11938334SJose.Borrego@Sun.COM param->buffer = NDR_MALLOC(mxa, input_bufsize); 11947961SNatalie.Li@Sun.COM if (param->buffer == NULL) { 11957961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); 11968334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 11977961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 11988334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 11997961SNatalie.Li@Sun.COM } 12007961SNatalie.Li@Sun.COM bzero(param->buffer, input_bufsize); 12017961SNatalie.Li@Sun.COM 12027961SNatalie.Li@Sun.COM status = ERROR_SUCCESS; 12037961SNatalie.Li@Sun.COM switch (param->info_level) { 12047961SNatalie.Li@Sun.COM case SERVICE_CONFIG_DESCRIPTION: 12057961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 12067961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 12077961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) { 12087961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 12097961SNatalie.Li@Sun.COM break; 12107961SNatalie.Li@Sun.COM } 12117961SNatalie.Li@Sun.COM 12127961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 12137961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_desc == NULL) { 12147961SNatalie.Li@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST; 12157961SNatalie.Li@Sun.COM break; 12167961SNatalie.Li@Sun.COM } 12177961SNatalie.Li@Sun.COM 12187961SNatalie.Li@Sun.COM desc = svc->sn_desc; 12197961SNatalie.Li@Sun.COM bytes_needed = SVCCTL_WNSTRLEN(desc); 12207961SNatalie.Li@Sun.COM 12217961SNatalie.Li@Sun.COM if (input_bufsize <= bytes_needed) { 12227961SNatalie.Li@Sun.COM param->bytes_needed = bytes_needed; 1223*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER; 12248334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12257961SNatalie.Li@Sun.COM } 12267961SNatalie.Li@Sun.COM 12277961SNatalie.Li@Sun.COM offset = sizeof (svc_description_t); 12287961SNatalie.Li@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 12297961SNatalie.Li@Sun.COM svc_desc = (svc_description_t *)param->buffer; 12307961SNatalie.Li@Sun.COM svc_desc->desc = offset; 12317961SNatalie.Li@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 12327961SNatalie.Li@Sun.COM wide_desc = (mts_wchar_t *)¶m->buffer[offset]; 12337961SNatalie.Li@Sun.COM (void) mts_mbstowcs(wide_desc, desc, (strlen(desc) + 1)); 12347961SNatalie.Li@Sun.COM offset = SVCCTL_WNSTRLEN(desc); 12357961SNatalie.Li@Sun.COM 12367961SNatalie.Li@Sun.COM param->bytes_needed = offset; 12377961SNatalie.Li@Sun.COM break; 12387961SNatalie.Li@Sun.COM 12397961SNatalie.Li@Sun.COM case SERVICE_CONFIG_FAILURE_ACTIONS: 12407961SNatalie.Li@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 12417961SNatalie.Li@Sun.COM fac = (svc_failure_actions_t *)param->buffer; 12427961SNatalie.Li@Sun.COM bzero(fac, sizeof (svc_failure_actions_t)); 12437961SNatalie.Li@Sun.COM 12447961SNatalie.Li@Sun.COM param->bytes_needed = input_bufsize; 12457961SNatalie.Li@Sun.COM break; 12467961SNatalie.Li@Sun.COM 12477961SNatalie.Li@Sun.COM default: 12487961SNatalie.Li@Sun.COM status = ERROR_INVALID_LEVEL; 12497961SNatalie.Li@Sun.COM break; 12507961SNatalie.Li@Sun.COM } 12517961SNatalie.Li@Sun.COM 12527961SNatalie.Li@Sun.COM if (status != ERROR_SUCCESS) { 12537961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); 12548334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 12557961SNatalie.Li@Sun.COM param->status = status; 12568334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12577961SNatalie.Li@Sun.COM } 12587961SNatalie.Li@Sun.COM 12597961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 12608334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12617961SNatalie.Li@Sun.COM } 1262*10001SJoyce.McIntosh@Sun.COM 1263*10001SJoyce.McIntosh@Sun.COM /* 1264*10001SJoyce.McIntosh@Sun.COM * svcctl_s_QueryServiceStatusEx 1265*10001SJoyce.McIntosh@Sun.COM */ 1266*10001SJoyce.McIntosh@Sun.COM static int 1267*10001SJoyce.McIntosh@Sun.COM svcctl_s_QueryServiceStatusEx(void *arg, ndr_xa_t *mxa) 1268*10001SJoyce.McIntosh@Sun.COM { 1269*10001SJoyce.McIntosh@Sun.COM struct svcctl_QueryServiceStatusEx *param = arg; 1270*10001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 1271*10001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 1272*10001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 1273*10001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx; 1274*10001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc; 1275*10001SJoyce.McIntosh@Sun.COM svc_status_ex_t *svc_status_ex; 1276*10001SJoyce.McIntosh@Sun.COM uint32_t input_bufsize; 1277*10001SJoyce.McIntosh@Sun.COM uint32_t bytes_needed; 1278*10001SJoyce.McIntosh@Sun.COM DWORD status; 1279*10001SJoyce.McIntosh@Sun.COM 1280*10001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 1281*10001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 1282*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 1283*10001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 1284*10001SJoyce.McIntosh@Sun.COM } 1285*10001SJoyce.McIntosh@Sun.COM 1286*10001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 1287*10001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 1288*10001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) { 1289*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 1290*10001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 1291*10001SJoyce.McIntosh@Sun.COM } 1292*10001SJoyce.McIntosh@Sun.COM 1293*10001SJoyce.McIntosh@Sun.COM if (param->info_level != SC_STATUS_PROCESS_INFO) { 1294*10001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER; 1295*10001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 1296*10001SJoyce.McIntosh@Sun.COM } 1297*10001SJoyce.McIntosh@Sun.COM 1298*10001SJoyce.McIntosh@Sun.COM bytes_needed = sizeof (struct svcctl_QueryServiceStatusEx); 1299*10001SJoyce.McIntosh@Sun.COM 1300*10001SJoyce.McIntosh@Sun.COM if ((input_bufsize = param->buf_size) < bytes_needed) { 1301*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatusEx)); 1302*10001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize; 1303*10001SJoyce.McIntosh@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 1304*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = bytes_needed; 1305*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER; 1306*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1307*10001SJoyce.McIntosh@Sun.COM } 1308*10001SJoyce.McIntosh@Sun.COM 1309*10001SJoyce.McIntosh@Sun.COM if ((svc_status_ex = NDR_MALLOC(mxa, bytes_needed)) == NULL) { 1310*10001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 1311*10001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 1312*10001SJoyce.McIntosh@Sun.COM } 1313*10001SJoyce.McIntosh@Sun.COM 1314*10001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 1315*10001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) { 1316*10001SJoyce.McIntosh@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST; 1317*10001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 1318*10001SJoyce.McIntosh@Sun.COM } 1319*10001SJoyce.McIntosh@Sun.COM 1320*10001SJoyce.McIntosh@Sun.COM svc_status_ex->service_type = SERVICE_WIN32_SHARE_PROCESS; 1321*10001SJoyce.McIntosh@Sun.COM svc_status_ex->cur_state = svcctl_scm_map_status(svc->sn_state); 1322*10001SJoyce.McIntosh@Sun.COM svc_status_ex->ctrl_accepted = 0; 1323*10001SJoyce.McIntosh@Sun.COM svc_status_ex->w32_exitcode = 0; 1324*10001SJoyce.McIntosh@Sun.COM svc_status_ex->svc_specified_exitcode = 0; 1325*10001SJoyce.McIntosh@Sun.COM svc_status_ex->check_point = 0; 1326*10001SJoyce.McIntosh@Sun.COM svc_status_ex->wait_hint = 0; 1327*10001SJoyce.McIntosh@Sun.COM svc_status_ex->process_id = 1; 1328*10001SJoyce.McIntosh@Sun.COM svc_status_ex->service_flags = 1; 1329*10001SJoyce.McIntosh@Sun.COM 1330*10001SJoyce.McIntosh@Sun.COM param->buffer = (uint8_t *)svc_status_ex; 1331*10001SJoyce.McIntosh@Sun.COM param->buf_size = bytes_needed; 1332*10001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 1333*10001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 1334*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1335*10001SJoyce.McIntosh@Sun.COM 1336*10001SJoyce.McIntosh@Sun.COM query_service_status_ex_error: 1337*10001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatusEx)); 1338*10001SJoyce.McIntosh@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 1339*10001SJoyce.McIntosh@Sun.COM param->status = status; 1340*10001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 1341*10001SJoyce.McIntosh@Sun.COM } 1342