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 /* 2210001SJoyce.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> 3910001SJoyce.McIntosh@Sun.COM #include <smbsrv/ntifs.h> 4010122SJordan.Brown@Sun.COM #include <smbsrv/winsvc.h> 4110122SJordan.Brown@Sun.COM #include <smbsrv/nterror.h> 4210122SJordan.Brown@Sun.COM #include <smbsrv/ndl/svcctl.ndl> 4310122SJordan.Brown@Sun.COM #include <smbsrv/libmlsvc.h> 447961SNatalie.Li@Sun.COM 4510001SJoyce.McIntosh@Sun.COM #define SVCCTL_SECURITY_BUFSIZE 256 4610001SJoyce.McIntosh@Sun.COM #define SVCCTL_ENUMSERVICES_MINBUFSIZE 1024 4710001SJoyce.McIntosh@Sun.COM 487961SNatalie.Li@Sun.COM #define SVCCTL_OPENSVC_OP_UNIMPLEMENTED(S) \ 497961SNatalie.Li@Sun.COM ((S) & SERVICE_CHANGE_CONFIG) || \ 507961SNatalie.Li@Sun.COM ((S) & SERVICE_PAUSE_CONTINUE) || \ 517961SNatalie.Li@Sun.COM ((S) & SERVICE_START) || \ 527961SNatalie.Li@Sun.COM ((S) & SERVICE_STOP) || \ 537961SNatalie.Li@Sun.COM ((S) & SERVICE_ENUMERATE_DEPENDENTS) 547961SNatalie.Li@Sun.COM 5510504SKeyur.Desai@Sun.COM typedef union { 5610504SKeyur.Desai@Sun.COM uint8_t *svc_buf; 5710504SKeyur.Desai@Sun.COM svc_description_t *svc_desc; 5810504SKeyur.Desai@Sun.COM svc_failure_actions_t *svc_fac; 5910504SKeyur.Desai@Sun.COM svc_delayed_auto_start_t *svc_dstart; 6010504SKeyur.Desai@Sun.COM svc_config_failure_action_t *svc_cfa; 6110504SKeyur.Desai@Sun.COM } svc_config_rsp_t; 6210504SKeyur.Desai@Sun.COM 638334SJose.Borrego@Sun.COM static int svcctl_s_Close(void *, ndr_xa_t *); 6410001SJoyce.McIntosh@Sun.COM static int svcctl_s_ControlService(void *, ndr_xa_t *); 6510001SJoyce.McIntosh@Sun.COM static int svcctl_s_DeleteService(void *, ndr_xa_t *); 6610001SJoyce.McIntosh@Sun.COM static int svcctl_s_QueryServiceSecurity(void *, ndr_xa_t *); 6710001SJoyce.McIntosh@Sun.COM static int svcctl_s_SetServiceSecurity(void *, ndr_xa_t *); 688334SJose.Borrego@Sun.COM static int svcctl_s_OpenManager(void *, ndr_xa_t *); 698334SJose.Borrego@Sun.COM static int svcctl_s_OpenService(void *, ndr_xa_t *); 708334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceStatus(void *, ndr_xa_t *); 718334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceConfig(void *, ndr_xa_t *); 7210001SJoyce.McIntosh@Sun.COM static int svcctl_s_StartService(void *, ndr_xa_t *); 7310001SJoyce.McIntosh@Sun.COM static int svcctl_s_EnumDependentServices(void *, ndr_xa_t *); 748334SJose.Borrego@Sun.COM static int svcctl_s_EnumServicesStatus(void *, ndr_xa_t *); 758334SJose.Borrego@Sun.COM static int svcctl_s_GetServiceDisplayNameW(void *, ndr_xa_t *); 768334SJose.Borrego@Sun.COM static int svcctl_s_GetServiceKeyNameW(void *, ndr_xa_t *); 7710001SJoyce.McIntosh@Sun.COM static int svcctl_s_OpenSCManagerA(void *, ndr_xa_t *); 7810001SJoyce.McIntosh@Sun.COM static int svcctl_s_OpenServiceA(void *, ndr_xa_t *); 7910001SJoyce.McIntosh@Sun.COM static int svcctl_s_EnumServicesStatusA(void *, ndr_xa_t *); 808334SJose.Borrego@Sun.COM static int svcctl_s_QueryServiceConfig2W(void *, ndr_xa_t *); 8110001SJoyce.McIntosh@Sun.COM static int svcctl_s_QueryServiceStatusEx(void *, ndr_xa_t *); 827961SNatalie.Li@Sun.COM 838334SJose.Borrego@Sun.COM static ndr_stub_table_t svcctl_stub_table[] = { 847961SNatalie.Li@Sun.COM { svcctl_s_Close, SVCCTL_OPNUM_Close }, 8510001SJoyce.McIntosh@Sun.COM { svcctl_s_ControlService, SVCCTL_OPNUM_ControlService }, 8610001SJoyce.McIntosh@Sun.COM { svcctl_s_DeleteService, SVCCTL_OPNUM_DeleteService }, 8710001SJoyce.McIntosh@Sun.COM { svcctl_s_QueryServiceSecurity, SVCCTL_OPNUM_QueryServiceSecurity }, 8810001SJoyce.McIntosh@Sun.COM { svcctl_s_SetServiceSecurity, SVCCTL_OPNUM_SetServiceSecurity }, 897961SNatalie.Li@Sun.COM { svcctl_s_OpenManager, SVCCTL_OPNUM_OpenManager }, 907961SNatalie.Li@Sun.COM { svcctl_s_OpenService, SVCCTL_OPNUM_OpenService }, 917961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceStatus, SVCCTL_OPNUM_QueryServiceStatus }, 927961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceConfig, SVCCTL_OPNUM_QueryServiceConfig }, 9310001SJoyce.McIntosh@Sun.COM { svcctl_s_StartService, SVCCTL_OPNUM_StartService }, 9410001SJoyce.McIntosh@Sun.COM { svcctl_s_EnumDependentServices, 9510001SJoyce.McIntosh@Sun.COM SVCCTL_OPNUM_EnumDependentServices }, 967961SNatalie.Li@Sun.COM { svcctl_s_EnumServicesStatus, SVCCTL_OPNUM_EnumServicesStatus }, 977961SNatalie.Li@Sun.COM { svcctl_s_GetServiceDisplayNameW, 987961SNatalie.Li@Sun.COM SVCCTL_OPNUM_GetServiceDisplayNameW }, 997961SNatalie.Li@Sun.COM { svcctl_s_GetServiceKeyNameW, SVCCTL_OPNUM_GetServiceKeyNameW }, 10010001SJoyce.McIntosh@Sun.COM { svcctl_s_OpenSCManagerA, SVCCTL_OPNUM_OpenSCManagerA }, 10110001SJoyce.McIntosh@Sun.COM { svcctl_s_OpenServiceA, SVCCTL_OPNUM_OpenServiceA }, 10210001SJoyce.McIntosh@Sun.COM { svcctl_s_EnumServicesStatusA, SVCCTL_OPNUM_EnumServicesStatusA }, 1037961SNatalie.Li@Sun.COM { svcctl_s_QueryServiceConfig2W, SVCCTL_OPNUM_QueryServiceConfig2W }, 10410001SJoyce.McIntosh@Sun.COM { svcctl_s_QueryServiceStatusEx, SVCCTL_OPNUM_QueryServiceStatusEx }, 1057961SNatalie.Li@Sun.COM {0} 1067961SNatalie.Li@Sun.COM }; 1077961SNatalie.Li@Sun.COM 1088334SJose.Borrego@Sun.COM static ndr_service_t svcctl_service = { 1097961SNatalie.Li@Sun.COM "SVCCTL", /* name */ 1107961SNatalie.Li@Sun.COM "Service Control Services", /* desc */ 1117961SNatalie.Li@Sun.COM "\\svcctl", /* endpoint */ 1127961SNatalie.Li@Sun.COM PIPE_NTSVCS, /* sec_addr_port */ 1138334SJose.Borrego@Sun.COM "367abb81-9844-35f1-ad32-98f038001003", 2, /* abstract */ 1148334SJose.Borrego@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 1157961SNatalie.Li@Sun.COM 0, /* no bind_instance_size */ 1167961SNatalie.Li@Sun.COM 0, /* no bind_req() */ 1177961SNatalie.Li@Sun.COM 0, /* no unbind_and_close() */ 1187961SNatalie.Li@Sun.COM 0, /* use generic_call_stub() */ 1197961SNatalie.Li@Sun.COM &TYPEINFO(svcctl_interface), /* interface ti */ 1207961SNatalie.Li@Sun.COM svcctl_stub_table /* stub_table */ 1217961SNatalie.Li@Sun.COM }; 1227961SNatalie.Li@Sun.COM 1237961SNatalie.Li@Sun.COM /* 1247961SNatalie.Li@Sun.COM * svcctl_initialize 1257961SNatalie.Li@Sun.COM * 1267961SNatalie.Li@Sun.COM * This function registers the SVCCTL RPC interface with the RPC runtime 1277961SNatalie.Li@Sun.COM * library. It must be called in order to use either the client side 1287961SNatalie.Li@Sun.COM * or the server side functions. 1297961SNatalie.Li@Sun.COM */ 1307961SNatalie.Li@Sun.COM void 1317961SNatalie.Li@Sun.COM svcctl_initialize(void) 1327961SNatalie.Li@Sun.COM { 1338334SJose.Borrego@Sun.COM (void) ndr_svc_register(&svcctl_service); 13410122SJordan.Brown@Sun.COM svcctl_init(); 13510122SJordan.Brown@Sun.COM } 13610122SJordan.Brown@Sun.COM 13710122SJordan.Brown@Sun.COM void 13810122SJordan.Brown@Sun.COM svcctl_finalize(void) 13910122SJordan.Brown@Sun.COM { 14010122SJordan.Brown@Sun.COM svcctl_fini(); 1417961SNatalie.Li@Sun.COM } 1427961SNatalie.Li@Sun.COM 1437961SNatalie.Li@Sun.COM /* 1447961SNatalie.Li@Sun.COM * svcctl_hdlookup 1457961SNatalie.Li@Sun.COM * 1467961SNatalie.Li@Sun.COM * Handle lookup wrapper to validate the local service and/or manager context. 1477961SNatalie.Li@Sun.COM */ 1487961SNatalie.Li@Sun.COM static ndr_handle_t * 1497961SNatalie.Li@Sun.COM svcctl_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, svcctl_context_type_t type) 1507961SNatalie.Li@Sun.COM { 1517961SNatalie.Li@Sun.COM ndr_handle_t *hd; 1527961SNatalie.Li@Sun.COM svcctl_context_t *ctx; 1537961SNatalie.Li@Sun.COM 1547961SNatalie.Li@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) 1557961SNatalie.Li@Sun.COM return (NULL); 1567961SNatalie.Li@Sun.COM 1577961SNatalie.Li@Sun.COM if ((ctx = (svcctl_context_t *)hd->nh_data) == NULL) 1587961SNatalie.Li@Sun.COM return (NULL); 1597961SNatalie.Li@Sun.COM 1607961SNatalie.Li@Sun.COM if ((ctx->c_type != type) || (ctx->c_ctx.uc_cp == NULL)) 1617961SNatalie.Li@Sun.COM return (NULL); 1627961SNatalie.Li@Sun.COM 1637961SNatalie.Li@Sun.COM return (hd); 1647961SNatalie.Li@Sun.COM } 1657961SNatalie.Li@Sun.COM 1667961SNatalie.Li@Sun.COM /* 1677961SNatalie.Li@Sun.COM * svcctl_hdfree 1687961SNatalie.Li@Sun.COM * 1697961SNatalie.Li@Sun.COM * Handle deallocation wrapper to free the local service and/or manager context. 1707961SNatalie.Li@Sun.COM */ 1717961SNatalie.Li@Sun.COM static void 1727961SNatalie.Li@Sun.COM svcctl_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id) 1737961SNatalie.Li@Sun.COM { 1747961SNatalie.Li@Sun.COM ndr_handle_t *hd; 1757961SNatalie.Li@Sun.COM svcctl_context_t *ctx; 1767961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 1777961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 1787961SNatalie.Li@Sun.COM 1797961SNatalie.Li@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 1807961SNatalie.Li@Sun.COM ctx = (svcctl_context_t *)hd->nh_data; 1817961SNatalie.Li@Sun.COM 1827961SNatalie.Li@Sun.COM switch (ctx->c_type) { 1837961SNatalie.Li@Sun.COM case SVCCTL_MANAGER_CONTEXT: 1847961SNatalie.Li@Sun.COM mgr_ctx = ctx->c_ctx.uc_mgr; 1857961SNatalie.Li@Sun.COM svcctl_scm_fini(mgr_ctx); 1867961SNatalie.Li@Sun.COM svcctl_scm_scf_handle_fini(mgr_ctx); 1877961SNatalie.Li@Sun.COM free(mgr_ctx); 1887961SNatalie.Li@Sun.COM break; 1897961SNatalie.Li@Sun.COM 1907961SNatalie.Li@Sun.COM case SVCCTL_SERVICE_CONTEXT: 1917961SNatalie.Li@Sun.COM svc_ctx = ctx->c_ctx.uc_svc; 1927961SNatalie.Li@Sun.COM free(svc_ctx->sc_mgrid); 1937961SNatalie.Li@Sun.COM free(svc_ctx->sc_svcname); 1947961SNatalie.Li@Sun.COM free(svc_ctx); 1957961SNatalie.Li@Sun.COM break; 1967961SNatalie.Li@Sun.COM 1977961SNatalie.Li@Sun.COM default: 1987961SNatalie.Li@Sun.COM break; 1997961SNatalie.Li@Sun.COM } 2007961SNatalie.Li@Sun.COM 2017961SNatalie.Li@Sun.COM free(ctx); 2027961SNatalie.Li@Sun.COM ndr_hdfree(mxa, id); 2037961SNatalie.Li@Sun.COM } 2047961SNatalie.Li@Sun.COM } 2057961SNatalie.Li@Sun.COM 2067961SNatalie.Li@Sun.COM /* 2077961SNatalie.Li@Sun.COM * svcctl_mgr_hdalloc 2087961SNatalie.Li@Sun.COM * 2097961SNatalie.Li@Sun.COM * Handle allocation wrapper to setup the local manager context. 2107961SNatalie.Li@Sun.COM */ 2117961SNatalie.Li@Sun.COM static ndr_hdid_t * 2127961SNatalie.Li@Sun.COM svcctl_mgr_hdalloc(ndr_xa_t *mxa) 2137961SNatalie.Li@Sun.COM { 2147961SNatalie.Li@Sun.COM svcctl_context_t *ctx; 2157961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 2167961SNatalie.Li@Sun.COM 2177961SNatalie.Li@Sun.COM if ((ctx = malloc(sizeof (svcctl_context_t))) == NULL) 2187961SNatalie.Li@Sun.COM return (NULL); 2197961SNatalie.Li@Sun.COM ctx->c_type = SVCCTL_MANAGER_CONTEXT; 2207961SNatalie.Li@Sun.COM 2217961SNatalie.Li@Sun.COM if ((mgr_ctx = malloc(sizeof (svcctl_manager_context_t))) == NULL) { 2227961SNatalie.Li@Sun.COM free(ctx); 2237961SNatalie.Li@Sun.COM return (NULL); 2247961SNatalie.Li@Sun.COM } 2257961SNatalie.Li@Sun.COM bzero(mgr_ctx, sizeof (svcctl_manager_context_t)); 2267961SNatalie.Li@Sun.COM 2277961SNatalie.Li@Sun.COM if (svcctl_scm_scf_handle_init(mgr_ctx) < 0) { 2287961SNatalie.Li@Sun.COM free(mgr_ctx); 2297961SNatalie.Li@Sun.COM free(ctx); 2307961SNatalie.Li@Sun.COM return (NULL); 2317961SNatalie.Li@Sun.COM } 2327961SNatalie.Li@Sun.COM 2337961SNatalie.Li@Sun.COM if (svcctl_scm_init(mgr_ctx) < 0) { 2347961SNatalie.Li@Sun.COM svcctl_scm_scf_handle_fini(mgr_ctx); 2357961SNatalie.Li@Sun.COM free(mgr_ctx); 2367961SNatalie.Li@Sun.COM free(ctx); 2377961SNatalie.Li@Sun.COM return (NULL); 2387961SNatalie.Li@Sun.COM } 2397961SNatalie.Li@Sun.COM 2407961SNatalie.Li@Sun.COM ctx->c_ctx.uc_mgr = mgr_ctx; 2417961SNatalie.Li@Sun.COM 2427961SNatalie.Li@Sun.COM return (ndr_hdalloc(mxa, ctx)); 2437961SNatalie.Li@Sun.COM } 2447961SNatalie.Li@Sun.COM 2457961SNatalie.Li@Sun.COM /* 2467961SNatalie.Li@Sun.COM * svcctl_get_mgr_ctx 2477961SNatalie.Li@Sun.COM * 2487961SNatalie.Li@Sun.COM * This function looks up a reference to local manager context. 2497961SNatalie.Li@Sun.COM */ 2507961SNatalie.Li@Sun.COM static svcctl_manager_context_t * 2517961SNatalie.Li@Sun.COM svcctl_get_mgr_ctx(ndr_xa_t *mxa, ndr_hdid_t *mgr_id) 2527961SNatalie.Li@Sun.COM { 2537961SNatalie.Li@Sun.COM ndr_handle_t *hd; 2547961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 2557961SNatalie.Li@Sun.COM 2567961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, mgr_id, SVCCTL_MANAGER_CONTEXT); 2577961SNatalie.Li@Sun.COM if (hd == NULL) 2587961SNatalie.Li@Sun.COM return (NULL); 2597961SNatalie.Li@Sun.COM 2607961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 2617961SNatalie.Li@Sun.COM 2627961SNatalie.Li@Sun.COM return (mgr_ctx); 2637961SNatalie.Li@Sun.COM } 2647961SNatalie.Li@Sun.COM 2657961SNatalie.Li@Sun.COM /* 2667961SNatalie.Li@Sun.COM * svcctl_svc_hdalloc 2677961SNatalie.Li@Sun.COM * 2687961SNatalie.Li@Sun.COM * Handle allocation wrapper to setup the local service context. 2697961SNatalie.Li@Sun.COM */ 2707961SNatalie.Li@Sun.COM static ndr_hdid_t * 2717961SNatalie.Li@Sun.COM svcctl_svc_hdalloc(ndr_xa_t *mxa, ndr_hdid_t *mgr_id, char *svc_name) 2727961SNatalie.Li@Sun.COM { 2737961SNatalie.Li@Sun.COM svcctl_context_t *ctx; 2747961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 2757961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 2767961SNatalie.Li@Sun.COM int max_name_sz = 0; 2777961SNatalie.Li@Sun.COM char *svcname; 2787961SNatalie.Li@Sun.COM 2797961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, mgr_id); 2807961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) 2817961SNatalie.Li@Sun.COM return (NULL); 2827961SNatalie.Li@Sun.COM max_name_sz = mgr_ctx->mc_scf_max_fmri_len; 2837961SNatalie.Li@Sun.COM 2847961SNatalie.Li@Sun.COM if ((ctx = malloc(sizeof (svcctl_context_t))) == NULL) { 2857961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id); 2867961SNatalie.Li@Sun.COM return (NULL); 2877961SNatalie.Li@Sun.COM } 2887961SNatalie.Li@Sun.COM ctx->c_type = SVCCTL_SERVICE_CONTEXT; 2897961SNatalie.Li@Sun.COM 2907961SNatalie.Li@Sun.COM if ((svc_ctx = malloc(sizeof (svcctl_service_context_t))) == NULL) { 2917961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id); 2927961SNatalie.Li@Sun.COM free(ctx); 2937961SNatalie.Li@Sun.COM return (NULL); 2947961SNatalie.Li@Sun.COM } 2957961SNatalie.Li@Sun.COM bzero(svc_ctx, sizeof (svcctl_service_context_t)); 2967961SNatalie.Li@Sun.COM 2977961SNatalie.Li@Sun.COM svc_ctx->sc_mgrid = malloc(sizeof (ndr_hdid_t)); 2987961SNatalie.Li@Sun.COM svcname = malloc(max_name_sz); 2997961SNatalie.Li@Sun.COM 3007961SNatalie.Li@Sun.COM if ((svc_ctx->sc_mgrid == NULL) || (svcname == NULL)) { 3017961SNatalie.Li@Sun.COM free(svc_ctx->sc_mgrid); 3027961SNatalie.Li@Sun.COM free(svc_ctx); 3037961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, mgr_id); 3047961SNatalie.Li@Sun.COM free(ctx); 3057961SNatalie.Li@Sun.COM return (NULL); 3067961SNatalie.Li@Sun.COM } 3077961SNatalie.Li@Sun.COM 3087961SNatalie.Li@Sun.COM svc_ctx->sc_svcname = svcname; 3097961SNatalie.Li@Sun.COM 3107961SNatalie.Li@Sun.COM bcopy(mgr_id, svc_ctx->sc_mgrid, sizeof (ndr_hdid_t)); 3117961SNatalie.Li@Sun.COM (void) strlcpy(svc_ctx->sc_svcname, svc_name, max_name_sz); 3127961SNatalie.Li@Sun.COM 3137961SNatalie.Li@Sun.COM ctx->c_ctx.uc_svc = svc_ctx; 3147961SNatalie.Li@Sun.COM 3157961SNatalie.Li@Sun.COM return (ndr_hdalloc(mxa, ctx)); 3167961SNatalie.Li@Sun.COM } 3177961SNatalie.Li@Sun.COM 3187961SNatalie.Li@Sun.COM /* 3197961SNatalie.Li@Sun.COM * svcctl_s_Close 3207961SNatalie.Li@Sun.COM * 3217961SNatalie.Li@Sun.COM * This is a request to close the SVCCTL interface specified by the 3227961SNatalie.Li@Sun.COM * handle. Free the handle and zero out the result handle for the 3237961SNatalie.Li@Sun.COM * client. 3247961SNatalie.Li@Sun.COM * 3257961SNatalie.Li@Sun.COM * Returns: 3267961SNatalie.Li@Sun.COM * ERROR_SUCCESS 3277961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 3287961SNatalie.Li@Sun.COM */ 3297961SNatalie.Li@Sun.COM static int 3308334SJose.Borrego@Sun.COM svcctl_s_Close(void *arg, ndr_xa_t *mxa) 3317961SNatalie.Li@Sun.COM { 3327961SNatalie.Li@Sun.COM struct svcctl_Close *param = arg; 3337961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 3347961SNatalie.Li@Sun.COM 3357961SNatalie.Li@Sun.COM svcctl_hdfree(mxa, id); 3367961SNatalie.Li@Sun.COM 3377961SNatalie.Li@Sun.COM bzero(¶m->result_handle, sizeof (svcctl_handle_t)); 3387961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 3398334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 3407961SNatalie.Li@Sun.COM } 3417961SNatalie.Li@Sun.COM 3427961SNatalie.Li@Sun.COM /* 34310001SJoyce.McIntosh@Sun.COM * svcctl_s_ControlService 34410001SJoyce.McIntosh@Sun.COM */ 34510001SJoyce.McIntosh@Sun.COM static int 34610001SJoyce.McIntosh@Sun.COM svcctl_s_ControlService(void *arg, ndr_xa_t *mxa) 34710001SJoyce.McIntosh@Sun.COM { 34810001SJoyce.McIntosh@Sun.COM struct svcctl_ControlService *param = arg; 34910001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 35010001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 35110001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 35210001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx; 35310001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc; 35410001SJoyce.McIntosh@Sun.COM 35510001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 35610001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 35710001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService)); 35810001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 35910001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 36010001SJoyce.McIntosh@Sun.COM } 36110001SJoyce.McIntosh@Sun.COM 36210001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 36310001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 36410001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) { 36510001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService)); 36610001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 36710001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 36810001SJoyce.McIntosh@Sun.COM } 36910001SJoyce.McIntosh@Sun.COM 37010001SJoyce.McIntosh@Sun.COM switch (param->control) { 37110001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_STOP: 37210001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_PAUSE: 37310001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_CONTINUE: 37410001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_INTERROGATE: 37510001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_SHUTDOWN: 37610001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_PARAMCHANGE: 37710001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDADD: 37810001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDREMOVE: 37910001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDENABLE: 38010001SJoyce.McIntosh@Sun.COM case SERVICE_CONTROL_NETBINDDISABLE: 38110001SJoyce.McIntosh@Sun.COM break; 38210001SJoyce.McIntosh@Sun.COM default: 38310001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService)); 38410001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_PARAMETER; 38510001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 38610001SJoyce.McIntosh@Sun.COM } 38710001SJoyce.McIntosh@Sun.COM 38810001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 38910001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) { 39010001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_ControlService)); 39110001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 39210001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 39310001SJoyce.McIntosh@Sun.COM } 39410001SJoyce.McIntosh@Sun.COM 39510001SJoyce.McIntosh@Sun.COM param->service_status.service_type = SERVICE_WIN32_SHARE_PROCESS; 39610001SJoyce.McIntosh@Sun.COM param->service_status.cur_state = svcctl_scm_map_status(svc->sn_state); 39710001SJoyce.McIntosh@Sun.COM param->service_status.ctrl_accepted = 0; 39810001SJoyce.McIntosh@Sun.COM param->service_status.w32_exitcode = 0; 39910001SJoyce.McIntosh@Sun.COM param->service_status.svc_specified_exitcode = 0; 40010001SJoyce.McIntosh@Sun.COM param->service_status.check_point = 0; 40110001SJoyce.McIntosh@Sun.COM param->service_status.wait_hint = 0; 40210001SJoyce.McIntosh@Sun.COM 40310001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 40410001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 40510001SJoyce.McIntosh@Sun.COM } 40610001SJoyce.McIntosh@Sun.COM 40710001SJoyce.McIntosh@Sun.COM /* 40810001SJoyce.McIntosh@Sun.COM * svcctl_s_DeleteService 40910001SJoyce.McIntosh@Sun.COM */ 41010001SJoyce.McIntosh@Sun.COM static int 41110001SJoyce.McIntosh@Sun.COM svcctl_s_DeleteService(void *arg, ndr_xa_t *mxa) 41210001SJoyce.McIntosh@Sun.COM { 41310001SJoyce.McIntosh@Sun.COM struct svcctl_DeleteService *param = arg; 41410001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 41510001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 41610001SJoyce.McIntosh@Sun.COM 41710001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 41810001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 41910001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 42010001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 42110001SJoyce.McIntosh@Sun.COM } 42210001SJoyce.McIntosh@Sun.COM 42310001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 42410001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 42510001SJoyce.McIntosh@Sun.COM } 42610001SJoyce.McIntosh@Sun.COM 42710001SJoyce.McIntosh@Sun.COM /* 42810001SJoyce.McIntosh@Sun.COM * svcctl_s_QueryServiceSecurity 42910001SJoyce.McIntosh@Sun.COM */ 43010001SJoyce.McIntosh@Sun.COM static int 43110001SJoyce.McIntosh@Sun.COM svcctl_s_QueryServiceSecurity(void *arg, ndr_xa_t *mxa) 43210001SJoyce.McIntosh@Sun.COM { 43310001SJoyce.McIntosh@Sun.COM struct svcctl_QueryServiceSecurity *param = arg; 43410001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 43510001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 43610001SJoyce.McIntosh@Sun.COM uint32_t sec_info; 43710001SJoyce.McIntosh@Sun.COM uint32_t bytes_needed = 0; 43810001SJoyce.McIntosh@Sun.COM uint32_t status; 43910001SJoyce.McIntosh@Sun.COM 44010001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 44110001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 44210001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 44310001SJoyce.McIntosh@Sun.COM goto query_service_security_error; 44410001SJoyce.McIntosh@Sun.COM } 44510001SJoyce.McIntosh@Sun.COM 44610001SJoyce.McIntosh@Sun.COM sec_info = param->security_info & SMB_ALL_SECINFO; 44710001SJoyce.McIntosh@Sun.COM if (sec_info == 0) { 44810001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER; 44910001SJoyce.McIntosh@Sun.COM goto query_service_security_error; 45010001SJoyce.McIntosh@Sun.COM } 45110001SJoyce.McIntosh@Sun.COM 45210001SJoyce.McIntosh@Sun.COM if (param->buf_size < SVCCTL_SECURITY_BUFSIZE) { 45310001SJoyce.McIntosh@Sun.COM bytes_needed = SVCCTL_SECURITY_BUFSIZE; 45410001SJoyce.McIntosh@Sun.COM status = ERROR_INSUFFICIENT_BUFFER; 45510001SJoyce.McIntosh@Sun.COM goto query_service_security_error; 45610001SJoyce.McIntosh@Sun.COM } 45710001SJoyce.McIntosh@Sun.COM 45810001SJoyce.McIntosh@Sun.COM param->buffer = NDR_MALLOC(mxa, SVCCTL_SECURITY_BUFSIZE); 45910001SJoyce.McIntosh@Sun.COM if (param->buffer == NULL) { 46010001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 46110001SJoyce.McIntosh@Sun.COM goto query_service_security_error; 46210001SJoyce.McIntosh@Sun.COM } 46310001SJoyce.McIntosh@Sun.COM 46410001SJoyce.McIntosh@Sun.COM bzero(param->buffer, sizeof (SVCCTL_SECURITY_BUFSIZE)); 46510001SJoyce.McIntosh@Sun.COM param->buf_size = SVCCTL_SECURITY_BUFSIZE; 46610001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 46710001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 46810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 46910001SJoyce.McIntosh@Sun.COM 47010001SJoyce.McIntosh@Sun.COM query_service_security_error: 47110001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceSecurity)); 47210001SJoyce.McIntosh@Sun.COM param->buf_size = 0; 47310001SJoyce.McIntosh@Sun.COM param->buffer = NDR_MALLOC(mxa, sizeof (uint32_t)); 47410001SJoyce.McIntosh@Sun.COM param->bytes_needed = bytes_needed; 47510001SJoyce.McIntosh@Sun.COM param->status = status; 47610001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 47710001SJoyce.McIntosh@Sun.COM } 47810001SJoyce.McIntosh@Sun.COM 47910001SJoyce.McIntosh@Sun.COM 48010001SJoyce.McIntosh@Sun.COM /* 48110001SJoyce.McIntosh@Sun.COM * svcctl_s_SetServiceSecurity 48210001SJoyce.McIntosh@Sun.COM */ 48310001SJoyce.McIntosh@Sun.COM static int 48410001SJoyce.McIntosh@Sun.COM svcctl_s_SetServiceSecurity(void *arg, ndr_xa_t *mxa) 48510001SJoyce.McIntosh@Sun.COM { 48610001SJoyce.McIntosh@Sun.COM struct svcctl_SetServiceSecurity *param = arg; 48710001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 48810001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 48910001SJoyce.McIntosh@Sun.COM 49010001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 49110001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 49210001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 49310001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 49410001SJoyce.McIntosh@Sun.COM } 49510001SJoyce.McIntosh@Sun.COM 49610001SJoyce.McIntosh@Sun.COM if ((param->security_info & SMB_ALL_SECINFO) == 0) { 49710001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_PARAMETER; 49810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 49910001SJoyce.McIntosh@Sun.COM } 50010001SJoyce.McIntosh@Sun.COM 50110001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED; 50210001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 50310001SJoyce.McIntosh@Sun.COM } 50410001SJoyce.McIntosh@Sun.COM 50510001SJoyce.McIntosh@Sun.COM /* 5067961SNatalie.Li@Sun.COM * svcctl_s_OpenManager 5077961SNatalie.Li@Sun.COM * 5087961SNatalie.Li@Sun.COM * Request to open the service control manager. 5097961SNatalie.Li@Sun.COM * The caller must have administrator rights in order to open this 5107961SNatalie.Li@Sun.COM * interface. We don't support write (SC_MANAGER_LOCK) access. 5117961SNatalie.Li@Sun.COM * 5127961SNatalie.Li@Sun.COM * Returns: 5137961SNatalie.Li@Sun.COM * ERROR_SUCCESS 5147961SNatalie.Li@Sun.COM * ERROR_ACCESS_DENIED 5157961SNatalie.Li@Sun.COM * 5167961SNatalie.Li@Sun.COM * On success, returns a handle for use with subsequent svcctl requests. 5177961SNatalie.Li@Sun.COM */ 5187961SNatalie.Li@Sun.COM static int 5198334SJose.Borrego@Sun.COM svcctl_s_OpenManager(void *arg, ndr_xa_t *mxa) 5207961SNatalie.Li@Sun.COM { 5217961SNatalie.Li@Sun.COM struct svcctl_OpenManager *param = arg; 5227961SNatalie.Li@Sun.COM ndr_hdid_t *id = NULL; 5237961SNatalie.Li@Sun.COM int rc; 5247961SNatalie.Li@Sun.COM 5257961SNatalie.Li@Sun.COM rc = ndr_is_admin(mxa); 5267961SNatalie.Li@Sun.COM 5277961SNatalie.Li@Sun.COM if ((rc == 0) || (param->desired_access & SC_MANAGER_LOCK) != 0) { 5287961SNatalie.Li@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t)); 5297961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED; 5308334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5317961SNatalie.Li@Sun.COM } 5327961SNatalie.Li@Sun.COM 5337961SNatalie.Li@Sun.COM id = svcctl_mgr_hdalloc(mxa); 5347961SNatalie.Li@Sun.COM if (id) { 5357961SNatalie.Li@Sun.COM bcopy(id, ¶m->handle, sizeof (svcctl_handle_t)); 5367961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 5377961SNatalie.Li@Sun.COM } else { 5387961SNatalie.Li@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t)); 5397961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED; 5407961SNatalie.Li@Sun.COM } 5417961SNatalie.Li@Sun.COM 5428334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5437961SNatalie.Li@Sun.COM } 5447961SNatalie.Li@Sun.COM 5457961SNatalie.Li@Sun.COM /* 5467961SNatalie.Li@Sun.COM * svcctl_s_OpenService 5477961SNatalie.Li@Sun.COM * 5487961SNatalie.Li@Sun.COM * Return a handle for use with subsequent svcctl requests. 5497961SNatalie.Li@Sun.COM * 5507961SNatalie.Li@Sun.COM * Returns: 5517961SNatalie.Li@Sun.COM * ERROR_SUCCESS 5527961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 5537961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST 5547961SNatalie.Li@Sun.COM * ERROR_CALL_NOT_IMPLEMENTED 5557961SNatalie.Li@Sun.COM */ 5567961SNatalie.Li@Sun.COM static int 5578334SJose.Borrego@Sun.COM svcctl_s_OpenService(void *arg, ndr_xa_t *mxa) 5587961SNatalie.Li@Sun.COM { 5597961SNatalie.Li@Sun.COM struct svcctl_OpenService *param = arg; 5607961SNatalie.Li@Sun.COM ndr_hdid_t *mgrid = (ndr_hdid_t *)¶m->manager_handle; 5617961SNatalie.Li@Sun.COM ndr_hdid_t *id = NULL; 5627961SNatalie.Li@Sun.COM ndr_handle_t *hd; 5637961SNatalie.Li@Sun.COM DWORD status; 5647961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 5657961SNatalie.Li@Sun.COM char *svc_name = (char *)param->service_name; 5667961SNatalie.Li@Sun.COM boolean_t unimplemented_operations = B_FALSE; 5677961SNatalie.Li@Sun.COM 5687961SNatalie.Li@Sun.COM /* Allow service handle allocations for only status & config queries */ 5697961SNatalie.Li@Sun.COM unimplemented_operations = 5707961SNatalie.Li@Sun.COM SVCCTL_OPENSVC_OP_UNIMPLEMENTED(param->desired_access); 5717961SNatalie.Li@Sun.COM 5727961SNatalie.Li@Sun.COM if (unimplemented_operations) { 5737961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 5747961SNatalie.Li@Sun.COM param->status = ERROR_CALL_NOT_IMPLEMENTED; 5758334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5767961SNatalie.Li@Sun.COM } 5777961SNatalie.Li@Sun.COM 5787961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, mgrid, SVCCTL_MANAGER_CONTEXT); 5797961SNatalie.Li@Sun.COM if (hd == NULL) { 5807961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 5817961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 5828334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5837961SNatalie.Li@Sun.COM } 5847961SNatalie.Li@Sun.COM 5857961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 5867961SNatalie.Li@Sun.COM status = svcctl_scm_validate_service(mgr_ctx, svc_name); 5877961SNatalie.Li@Sun.COM if (status != ERROR_SUCCESS) { 5887961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 5897961SNatalie.Li@Sun.COM param->status = status; 5908334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 5917961SNatalie.Li@Sun.COM } 5927961SNatalie.Li@Sun.COM 5937961SNatalie.Li@Sun.COM id = svcctl_svc_hdalloc(mxa, mgrid, svc_name); 5947961SNatalie.Li@Sun.COM if (id) { 5957961SNatalie.Li@Sun.COM bcopy(id, ¶m->service_handle, sizeof (svcctl_handle_t)); 5967961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 5977961SNatalie.Li@Sun.COM } else { 5987961SNatalie.Li@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 5997961SNatalie.Li@Sun.COM param->status = ERROR_ACCESS_DENIED; 6007961SNatalie.Li@Sun.COM } 6017961SNatalie.Li@Sun.COM 6028334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6037961SNatalie.Li@Sun.COM } 6047961SNatalie.Li@Sun.COM 6057961SNatalie.Li@Sun.COM /* 6067961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceStatus 6077961SNatalie.Li@Sun.COM * 6087961SNatalie.Li@Sun.COM * Returns: 6097961SNatalie.Li@Sun.COM * ERROR_SUCCESS 6107961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 6117961SNatalie.Li@Sun.COM */ 6127961SNatalie.Li@Sun.COM static int 6138334SJose.Borrego@Sun.COM svcctl_s_QueryServiceStatus(void *arg, ndr_xa_t *mxa) 6147961SNatalie.Li@Sun.COM { 6157961SNatalie.Li@Sun.COM struct svcctl_QueryServiceStatus *param = arg; 6167961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 6177961SNatalie.Li@Sun.COM ndr_handle_t *hd; 6187961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 6197961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 6207961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 6217961SNatalie.Li@Sun.COM 6227961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 6237961SNatalie.Li@Sun.COM if (hd == NULL) { 6247961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus)); 6257961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 6268334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6277961SNatalie.Li@Sun.COM } 6287961SNatalie.Li@Sun.COM 6297961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 6307961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 6317961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) { 63210001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus)); 6337961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 6348334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6357961SNatalie.Li@Sun.COM } 6367961SNatalie.Li@Sun.COM 6377961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 6387961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_state == NULL) { 63910001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatus)); 6407961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 6418334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6427961SNatalie.Li@Sun.COM } 6437961SNatalie.Li@Sun.COM 6447961SNatalie.Li@Sun.COM param->service_status.service_type = SERVICE_WIN32_SHARE_PROCESS; 6457961SNatalie.Li@Sun.COM param->service_status.cur_state = svcctl_scm_map_status(svc->sn_state); 6467961SNatalie.Li@Sun.COM param->service_status.ctrl_accepted = 0; 6477961SNatalie.Li@Sun.COM param->service_status.w32_exitcode = 0; 6487961SNatalie.Li@Sun.COM param->service_status.svc_specified_exitcode = 0; 6497961SNatalie.Li@Sun.COM param->service_status.check_point = 0; 6507961SNatalie.Li@Sun.COM param->service_status.wait_hint = 0; 6517961SNatalie.Li@Sun.COM 6527961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 6538334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 6547961SNatalie.Li@Sun.COM } 6557961SNatalie.Li@Sun.COM 6567961SNatalie.Li@Sun.COM /* 65710001SJoyce.McIntosh@Sun.COM * svcctl_s_EnumDependentServices 65810001SJoyce.McIntosh@Sun.COM * 65910001SJoyce.McIntosh@Sun.COM * Enumerate the list of services that depend on the specified service. 66010001SJoyce.McIntosh@Sun.COM */ 66110001SJoyce.McIntosh@Sun.COM static int 66210001SJoyce.McIntosh@Sun.COM svcctl_s_EnumDependentServices(void *arg, ndr_xa_t *mxa) 66310001SJoyce.McIntosh@Sun.COM { 66410001SJoyce.McIntosh@Sun.COM struct svcctl_EnumDependentServices *param = arg; 66510001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 66610001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 66710001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 66810001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx; 66910001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc; 67010001SJoyce.McIntosh@Sun.COM int input_bufsize = 0; 67110001SJoyce.McIntosh@Sun.COM uint32_t status; 67210001SJoyce.McIntosh@Sun.COM 67310001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 67410001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 67510001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 67610001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 67710001SJoyce.McIntosh@Sun.COM } 67810001SJoyce.McIntosh@Sun.COM 67910001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 68010001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 68110001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) { 68210001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 68310001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 68410001SJoyce.McIntosh@Sun.COM } 68510001SJoyce.McIntosh@Sun.COM 68610001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 68710001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) { 68810001SJoyce.McIntosh@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST; 68910001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 69010001SJoyce.McIntosh@Sun.COM } 69110001SJoyce.McIntosh@Sun.COM 69210001SJoyce.McIntosh@Sun.COM switch (param->svc_state) { 69310001SJoyce.McIntosh@Sun.COM case SERVICE_STOPPED: 69410001SJoyce.McIntosh@Sun.COM case SERVICE_START_PENDING: 69510001SJoyce.McIntosh@Sun.COM case SERVICE_STOP_PENDING: 69610001SJoyce.McIntosh@Sun.COM case SERVICE_RUNNING: 69710001SJoyce.McIntosh@Sun.COM case SERVICE_CONTINUE_PENDING: 69810001SJoyce.McIntosh@Sun.COM case SERVICE_PAUSE_PENDING: 69910001SJoyce.McIntosh@Sun.COM case SERVICE_PAUSED: 70010001SJoyce.McIntosh@Sun.COM break; 70110001SJoyce.McIntosh@Sun.COM default: 70210001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER; 70310001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 70410001SJoyce.McIntosh@Sun.COM } 70510001SJoyce.McIntosh@Sun.COM 70610001SJoyce.McIntosh@Sun.COM if ((input_bufsize = param->buf_size) == 0) { 70710001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumDependentServices)); 70810001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize; 70910001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, ""); 71010001SJoyce.McIntosh@Sun.COM param->bytes_needed = 1024; 71110001SJoyce.McIntosh@Sun.COM param->svc_num = 0; 71210001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA; 71310001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 71410001SJoyce.McIntosh@Sun.COM } 71510001SJoyce.McIntosh@Sun.COM 71610001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, input_bufsize); 71710001SJoyce.McIntosh@Sun.COM if (param->services == NULL) { 71810001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 71910001SJoyce.McIntosh@Sun.COM goto enum_dependent_services_error; 72010001SJoyce.McIntosh@Sun.COM } 72110001SJoyce.McIntosh@Sun.COM 72210001SJoyce.McIntosh@Sun.COM bzero(param->services, input_bufsize); 72310001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize; 72410001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 72510001SJoyce.McIntosh@Sun.COM param->svc_num = 0; 72610001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 72710001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 72810001SJoyce.McIntosh@Sun.COM 72910001SJoyce.McIntosh@Sun.COM enum_dependent_services_error: 73010001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumDependentServices)); 73110001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, ""); 73210001SJoyce.McIntosh@Sun.COM param->status = status; 73310001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 73410001SJoyce.McIntosh@Sun.COM } 73510001SJoyce.McIntosh@Sun.COM 73610001SJoyce.McIntosh@Sun.COM /* 7377961SNatalie.Li@Sun.COM * svcctl_s_EnumServicesStatus 7387961SNatalie.Li@Sun.COM * 73910001SJoyce.McIntosh@Sun.COM * Enumerate the list of services we support. 7407961SNatalie.Li@Sun.COM */ 7417961SNatalie.Li@Sun.COM static int 7428334SJose.Borrego@Sun.COM svcctl_s_EnumServicesStatus(void *arg, ndr_xa_t *mxa) 7437961SNatalie.Li@Sun.COM { 7447961SNatalie.Li@Sun.COM struct svcctl_EnumServicesStatus *param = arg; 7457961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; 7467961SNatalie.Li@Sun.COM ndr_handle_t *hd; 7477961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 74810001SJoyce.McIntosh@Sun.COM uint32_t buf_size = 0; 74910001SJoyce.McIntosh@Sun.COM uint32_t svc_num; 75010001SJoyce.McIntosh@Sun.COM uint32_t resume_handle = 0; 75110001SJoyce.McIntosh@Sun.COM uint32_t status; 75210001SJoyce.McIntosh@Sun.COM 75310001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL) 75410001SJoyce.McIntosh@Sun.COM resume_handle = *param->resume_handle; 7557961SNatalie.Li@Sun.COM 7567961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); 7577961SNatalie.Li@Sun.COM if (hd == NULL) { 75810001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 75910001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 7607961SNatalie.Li@Sun.COM } 7617961SNatalie.Li@Sun.COM 7627961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 7637961SNatalie.Li@Sun.COM if (svcctl_scm_refresh(mgr_ctx) != 0) { 76410001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 76510001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 7667961SNatalie.Li@Sun.COM } 7677961SNatalie.Li@Sun.COM 76810001SJoyce.McIntosh@Sun.COM buf_size = param->buf_size; 76910001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, buf_size); 7707961SNatalie.Li@Sun.COM if (param->services == NULL) { 77110001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 77210001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 7737961SNatalie.Li@Sun.COM } 77410001SJoyce.McIntosh@Sun.COM bzero(param->services, buf_size); 7757961SNatalie.Li@Sun.COM 77610001SJoyce.McIntosh@Sun.COM if (buf_size < SVCCTL_ENUMSERVICES_MINBUFSIZE) { 7777961SNatalie.Li@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed; 7787961SNatalie.Li@Sun.COM param->svc_num = 0; 77910001SJoyce.McIntosh@Sun.COM if (param->resume_handle) 78010001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0; 7817961SNatalie.Li@Sun.COM param->status = ERROR_MORE_DATA; 7828334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 7837961SNatalie.Li@Sun.COM } 7847961SNatalie.Li@Sun.COM 78510001SJoyce.McIntosh@Sun.COM svc_num = svcctl_scm_enum_services(mgr_ctx, param->services, 78610001SJoyce.McIntosh@Sun.COM buf_size, &resume_handle, B_TRUE); 78710001SJoyce.McIntosh@Sun.COM 78810001SJoyce.McIntosh@Sun.COM param->buf_size = buf_size; 78910001SJoyce.McIntosh@Sun.COM param->svc_num = svc_num; 7907961SNatalie.Li@Sun.COM 79110001SJoyce.McIntosh@Sun.COM if (resume_handle != 0) { 79210001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL) 79310001SJoyce.McIntosh@Sun.COM *param->resume_handle = resume_handle; 79410001SJoyce.McIntosh@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed; 79510001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA; 79610001SJoyce.McIntosh@Sun.COM } else { 79710001SJoyce.McIntosh@Sun.COM if (param->resume_handle) 79810001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0; 79910001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 80010001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 80110001SJoyce.McIntosh@Sun.COM } 80210001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 80310001SJoyce.McIntosh@Sun.COM 80410001SJoyce.McIntosh@Sun.COM enum_services_status_error: 80510001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumServicesStatus)); 80610001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, ""); 80710001SJoyce.McIntosh@Sun.COM param->status = status; 8088334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8097961SNatalie.Li@Sun.COM } 8107961SNatalie.Li@Sun.COM 8117961SNatalie.Li@Sun.COM /* 8127961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceConfig 8137961SNatalie.Li@Sun.COM * 8147961SNatalie.Li@Sun.COM * Returns: 8157961SNatalie.Li@Sun.COM * ERROR_SUCCESS 8167961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 8177961SNatalie.Li@Sun.COM */ 8187961SNatalie.Li@Sun.COM static int 8198334SJose.Borrego@Sun.COM svcctl_s_QueryServiceConfig(void *arg, ndr_xa_t *mxa) 8207961SNatalie.Li@Sun.COM { 8217961SNatalie.Li@Sun.COM struct svcctl_QueryServiceConfig *param = arg; 8227961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 8237961SNatalie.Li@Sun.COM ndr_handle_t *hd; 8247961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 8257961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 8267961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 8277961SNatalie.Li@Sun.COM int bytes_needed = 0; 8287961SNatalie.Li@Sun.COM svc_config_t *cfg; 8297961SNatalie.Li@Sun.COM 8307961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 8317961SNatalie.Li@Sun.COM if (hd == NULL) { 8327961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig)); 8337961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 8348334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8357961SNatalie.Li@Sun.COM } 8367961SNatalie.Li@Sun.COM 8377961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 8387961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 8397961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) { 8407961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig)); 8417961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 8428334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8437961SNatalie.Li@Sun.COM } 8447961SNatalie.Li@Sun.COM 8457961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 8467961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_fmri == NULL) { 8477961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig)); 8487961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 8498334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8507961SNatalie.Li@Sun.COM } 8517961SNatalie.Li@Sun.COM 8527961SNatalie.Li@Sun.COM cfg = ¶m->service_cfg; 8537961SNatalie.Li@Sun.COM cfg->service_type = SERVICE_WIN32_SHARE_PROCESS; 8547961SNatalie.Li@Sun.COM cfg->start_type = SERVICE_AUTO_START; 85510504SKeyur.Desai@Sun.COM cfg->error_control = SERVICE_ERROR_IGNORE; 8568334SJose.Borrego@Sun.COM cfg->binary_pathname = NDR_STRDUP(mxa, ""); 8578334SJose.Borrego@Sun.COM cfg->loadorder_group = NDR_STRDUP(mxa, ""); 8587961SNatalie.Li@Sun.COM cfg->tag_id = 0; 8598334SJose.Borrego@Sun.COM cfg->dependencies = NDR_STRDUP(mxa, ""); 8608334SJose.Borrego@Sun.COM cfg->service_startname = NDR_STRDUP(mxa, ""); 8618334SJose.Borrego@Sun.COM cfg->display_name = NDR_STRDUP(mxa, svc->sn_fmri); 8627961SNatalie.Li@Sun.COM 8637961SNatalie.Li@Sun.COM bytes_needed = sizeof (svc_config_t); 8647961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->binary_pathname); 8657961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->loadorder_group); 8667961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->dependencies); 8677961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN((const char *)cfg->service_startname); 8687961SNatalie.Li@Sun.COM bytes_needed += SVCCTL_WNSTRLEN(svc->sn_fmri); 8697961SNatalie.Li@Sun.COM 8707961SNatalie.Li@Sun.COM if (param->buf_size < bytes_needed) { 8717961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig)); 8727961SNatalie.Li@Sun.COM param->cfg_bytes = bytes_needed; 87310001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER; 8748334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8757961SNatalie.Li@Sun.COM } 8767961SNatalie.Li@Sun.COM 8777961SNatalie.Li@Sun.COM param->cfg_bytes = bytes_needed; 8787961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 8798334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 8807961SNatalie.Li@Sun.COM } 8817961SNatalie.Li@Sun.COM 8827961SNatalie.Li@Sun.COM /* 88310001SJoyce.McIntosh@Sun.COM * svcctl_s_StartService 88410001SJoyce.McIntosh@Sun.COM */ 88510001SJoyce.McIntosh@Sun.COM static int 88610001SJoyce.McIntosh@Sun.COM svcctl_s_StartService(void *arg, ndr_xa_t *mxa) 88710001SJoyce.McIntosh@Sun.COM { 88810001SJoyce.McIntosh@Sun.COM struct svcctl_StartService *param = arg; 88910001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 89010001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 89110001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 89210001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx; 89310001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc; 89410001SJoyce.McIntosh@Sun.COM 89510001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 89610001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 89710001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 89810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 89910001SJoyce.McIntosh@Sun.COM } 90010001SJoyce.McIntosh@Sun.COM 90110001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 90210001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 90310001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) { 90410001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 90510001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 90610001SJoyce.McIntosh@Sun.COM } 90710001SJoyce.McIntosh@Sun.COM 90810001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 90910001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_fmri == NULL) 91010001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 91110001SJoyce.McIntosh@Sun.COM else 91210001SJoyce.McIntosh@Sun.COM param->status = ERROR_SERVICE_ALREADY_RUNNING; 91310001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 91410001SJoyce.McIntosh@Sun.COM } 91510001SJoyce.McIntosh@Sun.COM 91610001SJoyce.McIntosh@Sun.COM 91710001SJoyce.McIntosh@Sun.COM /* 9187961SNatalie.Li@Sun.COM * svcctl_s_GetServiceDisplayNameW 9197961SNatalie.Li@Sun.COM * 9207961SNatalie.Li@Sun.COM * Returns: 9217961SNatalie.Li@Sun.COM * ERROR_SUCCESS 9227961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 9237961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST 9247961SNatalie.Li@Sun.COM */ 9257961SNatalie.Li@Sun.COM static int 9268334SJose.Borrego@Sun.COM svcctl_s_GetServiceDisplayNameW(void *arg, ndr_xa_t *mxa) 9277961SNatalie.Li@Sun.COM { 9287961SNatalie.Li@Sun.COM struct svcctl_GetServiceDisplayNameW *param = arg; 9297961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; 9307961SNatalie.Li@Sun.COM ndr_handle_t *hd; 9317961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 9327961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 9337961SNatalie.Li@Sun.COM 9347961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); 9357961SNatalie.Li@Sun.COM if (hd == NULL) { 9367961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); 9378334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, ""); 9387961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 9398334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9407961SNatalie.Li@Sun.COM } 9417961SNatalie.Li@Sun.COM 9427961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 9437961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, (char *)param->service_name); 9447961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_fmri == NULL) { 9457961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); 9468334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, ""); 9477961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 9488334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9497961SNatalie.Li@Sun.COM } 9507961SNatalie.Li@Sun.COM 9518334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, svc->sn_fmri); 9527961SNatalie.Li@Sun.COM if (param->display_name == NULL) { 9537961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceDisplayNameW)); 9548334SJose.Borrego@Sun.COM param->display_name = NDR_STRDUP(mxa, ""); 9557961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 9568334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9577961SNatalie.Li@Sun.COM } 9587961SNatalie.Li@Sun.COM 9597961SNatalie.Li@Sun.COM param->buf_size = strlen(svc->sn_fmri); 9607961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 9618334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9627961SNatalie.Li@Sun.COM } 9637961SNatalie.Li@Sun.COM 9647961SNatalie.Li@Sun.COM /* 9657961SNatalie.Li@Sun.COM * svcctl_s_GetServiceKeyNameW 9667961SNatalie.Li@Sun.COM * 9677961SNatalie.Li@Sun.COM * Returns: 9687961SNatalie.Li@Sun.COM * ERROR_SUCCESS 9697961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 9707961SNatalie.Li@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST 9717961SNatalie.Li@Sun.COM */ 9727961SNatalie.Li@Sun.COM static int 9738334SJose.Borrego@Sun.COM svcctl_s_GetServiceKeyNameW(void *arg, ndr_xa_t *mxa) 9747961SNatalie.Li@Sun.COM { 9757961SNatalie.Li@Sun.COM struct svcctl_GetServiceKeyNameW *param = arg; 9767961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; 9777961SNatalie.Li@Sun.COM ndr_handle_t *hd; 9787961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 9797961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 9807961SNatalie.Li@Sun.COM 9817961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); 9827961SNatalie.Li@Sun.COM if (hd == NULL) { 9837961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); 9848334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, ""); 9857961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 9868334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9877961SNatalie.Li@Sun.COM } 9887961SNatalie.Li@Sun.COM 9897961SNatalie.Li@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 9907961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, (char *)param->service_name); 9917961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_name == NULL) { 9927961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); 9938334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, ""); 9947961SNatalie.Li@Sun.COM param->status = ERROR_SERVICE_DOES_NOT_EXIST; 9958334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 9967961SNatalie.Li@Sun.COM } 9977961SNatalie.Li@Sun.COM 9988334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, svc->sn_name); 9997961SNatalie.Li@Sun.COM if (param->key_name == NULL) { 10007961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_GetServiceKeyNameW)); 10018334SJose.Borrego@Sun.COM param->key_name = NDR_STRDUP(mxa, ""); 10027961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 10038334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 10047961SNatalie.Li@Sun.COM } 10057961SNatalie.Li@Sun.COM 10067961SNatalie.Li@Sun.COM param->buf_size = strlen(svc->sn_name); 10077961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 10088334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 10097961SNatalie.Li@Sun.COM } 10107961SNatalie.Li@Sun.COM 10117961SNatalie.Li@Sun.COM /* 101210001SJoyce.McIntosh@Sun.COM * svcctl_s_OpenSCManagerA 101310001SJoyce.McIntosh@Sun.COM * 101410001SJoyce.McIntosh@Sun.COM * Request to open the service control manager. 101510001SJoyce.McIntosh@Sun.COM * The caller must have administrator rights in order to open this 101610001SJoyce.McIntosh@Sun.COM * interface. We don't support write (SC_MANAGER_LOCK) access. 101710001SJoyce.McIntosh@Sun.COM * 101810001SJoyce.McIntosh@Sun.COM * Returns: 101910001SJoyce.McIntosh@Sun.COM * ERROR_SUCCESS 102010001SJoyce.McIntosh@Sun.COM * ERROR_ACCESS_DENIED 102110001SJoyce.McIntosh@Sun.COM * 102210001SJoyce.McIntosh@Sun.COM * On success, returns a handle for use with subsequent svcctl requests. 102310001SJoyce.McIntosh@Sun.COM */ 102410001SJoyce.McIntosh@Sun.COM static int 102510001SJoyce.McIntosh@Sun.COM svcctl_s_OpenSCManagerA(void *arg, ndr_xa_t *mxa) 102610001SJoyce.McIntosh@Sun.COM { 102710001SJoyce.McIntosh@Sun.COM struct svcctl_OpenSCManagerA *param = arg; 102810001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = NULL; 102910001SJoyce.McIntosh@Sun.COM int rc; 103010001SJoyce.McIntosh@Sun.COM 103110001SJoyce.McIntosh@Sun.COM rc = ndr_is_admin(mxa); 103210001SJoyce.McIntosh@Sun.COM 103310001SJoyce.McIntosh@Sun.COM if ((rc == 0) || (param->desired_access & SC_MANAGER_LOCK) != 0) { 103410001SJoyce.McIntosh@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t)); 103510001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED; 103610001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 103710001SJoyce.McIntosh@Sun.COM } 103810001SJoyce.McIntosh@Sun.COM 103910001SJoyce.McIntosh@Sun.COM id = svcctl_mgr_hdalloc(mxa); 104010001SJoyce.McIntosh@Sun.COM if (id) { 104110001SJoyce.McIntosh@Sun.COM bcopy(id, ¶m->handle, sizeof (svcctl_handle_t)); 104210001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 104310001SJoyce.McIntosh@Sun.COM } else { 104410001SJoyce.McIntosh@Sun.COM bzero(¶m->handle, sizeof (svcctl_handle_t)); 104510001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED; 104610001SJoyce.McIntosh@Sun.COM } 104710001SJoyce.McIntosh@Sun.COM 104810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 104910001SJoyce.McIntosh@Sun.COM } 105010001SJoyce.McIntosh@Sun.COM 105110001SJoyce.McIntosh@Sun.COM /* 105210001SJoyce.McIntosh@Sun.COM * svcctl_s_OpenServiceA 105310001SJoyce.McIntosh@Sun.COM * 105410001SJoyce.McIntosh@Sun.COM * Return a handle for use with subsequent svcctl requests. 105510001SJoyce.McIntosh@Sun.COM * 105610001SJoyce.McIntosh@Sun.COM * Returns: 105710001SJoyce.McIntosh@Sun.COM * ERROR_SUCCESS 105810001SJoyce.McIntosh@Sun.COM * ERROR_INVALID_HANDLE 105910001SJoyce.McIntosh@Sun.COM * ERROR_SERVICE_DOES_NOT_EXIST 106010001SJoyce.McIntosh@Sun.COM * ERROR_CALL_NOT_IMPLEMENTED 106110001SJoyce.McIntosh@Sun.COM */ 106210001SJoyce.McIntosh@Sun.COM static int 106310001SJoyce.McIntosh@Sun.COM svcctl_s_OpenServiceA(void *arg, ndr_xa_t *mxa) 106410001SJoyce.McIntosh@Sun.COM { 106510001SJoyce.McIntosh@Sun.COM struct svcctl_OpenServiceA *param = arg; 106610001SJoyce.McIntosh@Sun.COM ndr_hdid_t *mgrid = (ndr_hdid_t *)¶m->manager_handle; 106710001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = NULL; 106810001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 106910001SJoyce.McIntosh@Sun.COM DWORD status; 107010001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 107110001SJoyce.McIntosh@Sun.COM char *svc_name = (char *)param->service_name->value; 107210001SJoyce.McIntosh@Sun.COM boolean_t unimplemented_operations = B_FALSE; 107310001SJoyce.McIntosh@Sun.COM 107410001SJoyce.McIntosh@Sun.COM /* Allow service handle allocations for only status & config queries */ 107510001SJoyce.McIntosh@Sun.COM unimplemented_operations = 107610001SJoyce.McIntosh@Sun.COM SVCCTL_OPENSVC_OP_UNIMPLEMENTED(param->desired_access); 107710001SJoyce.McIntosh@Sun.COM 107810001SJoyce.McIntosh@Sun.COM if (unimplemented_operations) { 107910001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 108010001SJoyce.McIntosh@Sun.COM param->status = ERROR_CALL_NOT_IMPLEMENTED; 108110001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 108210001SJoyce.McIntosh@Sun.COM } 108310001SJoyce.McIntosh@Sun.COM 108410001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, mgrid, SVCCTL_MANAGER_CONTEXT); 108510001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 108610001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 108710001SJoyce.McIntosh@Sun.COM param->status = ERROR_INVALID_HANDLE; 108810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 108910001SJoyce.McIntosh@Sun.COM } 109010001SJoyce.McIntosh@Sun.COM 109110001SJoyce.McIntosh@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 109210001SJoyce.McIntosh@Sun.COM status = svcctl_scm_validate_service(mgr_ctx, svc_name); 109310001SJoyce.McIntosh@Sun.COM if (status != ERROR_SUCCESS) { 109410001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 109510001SJoyce.McIntosh@Sun.COM param->status = status; 109610001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 109710001SJoyce.McIntosh@Sun.COM } 109810001SJoyce.McIntosh@Sun.COM 109910001SJoyce.McIntosh@Sun.COM id = svcctl_svc_hdalloc(mxa, mgrid, svc_name); 110010001SJoyce.McIntosh@Sun.COM if (id) { 110110001SJoyce.McIntosh@Sun.COM bcopy(id, ¶m->service_handle, sizeof (svcctl_handle_t)); 110210001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 110310001SJoyce.McIntosh@Sun.COM } else { 110410001SJoyce.McIntosh@Sun.COM bzero(¶m->service_handle, sizeof (svcctl_handle_t)); 110510001SJoyce.McIntosh@Sun.COM param->status = ERROR_ACCESS_DENIED; 110610001SJoyce.McIntosh@Sun.COM } 110710001SJoyce.McIntosh@Sun.COM 110810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 110910001SJoyce.McIntosh@Sun.COM } 111010001SJoyce.McIntosh@Sun.COM 111110001SJoyce.McIntosh@Sun.COM /* 111210001SJoyce.McIntosh@Sun.COM * svcctl_s_EnumServicesStatusA 111310001SJoyce.McIntosh@Sun.COM * 111410001SJoyce.McIntosh@Sun.COM * Enumerate the list of services we support as ASCII. 111510001SJoyce.McIntosh@Sun.COM */ 111610001SJoyce.McIntosh@Sun.COM static int 111710001SJoyce.McIntosh@Sun.COM svcctl_s_EnumServicesStatusA(void *arg, ndr_xa_t *mxa) 111810001SJoyce.McIntosh@Sun.COM { 111910001SJoyce.McIntosh@Sun.COM struct svcctl_EnumServicesStatusA *param = arg; 112010001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->manager_handle; 112110001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 112210001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 112310001SJoyce.McIntosh@Sun.COM uint32_t buf_size; 112410001SJoyce.McIntosh@Sun.COM uint32_t svc_num; 112510001SJoyce.McIntosh@Sun.COM uint32_t resume_handle = 0; 112610001SJoyce.McIntosh@Sun.COM uint32_t status; 112710001SJoyce.McIntosh@Sun.COM 112810001SJoyce.McIntosh@Sun.COM buf_size = param->buf_size; 112910001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL) 113010001SJoyce.McIntosh@Sun.COM resume_handle = *param->resume_handle; 113110001SJoyce.McIntosh@Sun.COM 113210001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_MANAGER_CONTEXT); 113310001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 113410001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 113510001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 113610001SJoyce.McIntosh@Sun.COM } 113710001SJoyce.McIntosh@Sun.COM 113810001SJoyce.McIntosh@Sun.COM mgr_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_mgr; 113910001SJoyce.McIntosh@Sun.COM if (svcctl_scm_refresh(mgr_ctx) != 0) { 114010001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 114110001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 114210001SJoyce.McIntosh@Sun.COM } 114310001SJoyce.McIntosh@Sun.COM 114410001SJoyce.McIntosh@Sun.COM param->services = NDR_MALLOC(mxa, buf_size); 114510001SJoyce.McIntosh@Sun.COM if (param->services == NULL) { 114610001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 114710001SJoyce.McIntosh@Sun.COM goto enum_services_status_error; 114810001SJoyce.McIntosh@Sun.COM } 114910001SJoyce.McIntosh@Sun.COM bzero(param->services, buf_size); 115010001SJoyce.McIntosh@Sun.COM 115110001SJoyce.McIntosh@Sun.COM svc_num = svcctl_scm_enum_services(mgr_ctx, param->services, 115210001SJoyce.McIntosh@Sun.COM buf_size, &resume_handle, B_FALSE); 115310001SJoyce.McIntosh@Sun.COM 115410001SJoyce.McIntosh@Sun.COM param->buf_size = buf_size; 115510001SJoyce.McIntosh@Sun.COM param->svc_num = svc_num; 115610001SJoyce.McIntosh@Sun.COM 115710001SJoyce.McIntosh@Sun.COM if (resume_handle != 0) { 115810001SJoyce.McIntosh@Sun.COM if (param->resume_handle != NULL) 115910001SJoyce.McIntosh@Sun.COM *param->resume_handle = resume_handle; 116010001SJoyce.McIntosh@Sun.COM param->bytes_needed = mgr_ctx->mc_bytes_needed; 116110001SJoyce.McIntosh@Sun.COM param->status = ERROR_MORE_DATA; 116210001SJoyce.McIntosh@Sun.COM } else { 116310001SJoyce.McIntosh@Sun.COM if (param->resume_handle) 116410001SJoyce.McIntosh@Sun.COM *param->resume_handle = 0; 116510001SJoyce.McIntosh@Sun.COM param->bytes_needed = 0; 116610001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 116710001SJoyce.McIntosh@Sun.COM } 116810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 116910001SJoyce.McIntosh@Sun.COM 117010001SJoyce.McIntosh@Sun.COM enum_services_status_error: 117110001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_EnumServicesStatusA)); 117210001SJoyce.McIntosh@Sun.COM param->services = NDR_STRDUP(mxa, ""); 117310001SJoyce.McIntosh@Sun.COM param->status = status; 117410001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 117510001SJoyce.McIntosh@Sun.COM } 117610001SJoyce.McIntosh@Sun.COM 117710001SJoyce.McIntosh@Sun.COM /* 11787961SNatalie.Li@Sun.COM * svcctl_s_QueryServiceConfig2W 11797961SNatalie.Li@Sun.COM * 11807961SNatalie.Li@Sun.COM * Returns: 11817961SNatalie.Li@Sun.COM * ERROR_SUCCESS 11827961SNatalie.Li@Sun.COM * ERROR_INVALID_HANDLE 11837961SNatalie.Li@Sun.COM * ERROR_INVALID_LEVEL 11847961SNatalie.Li@Sun.COM * ERROR_NOT_ENOUGH_MEMORY 11857961SNatalie.Li@Sun.COM */ 11867961SNatalie.Li@Sun.COM static int 11878334SJose.Borrego@Sun.COM svcctl_s_QueryServiceConfig2W(void *arg, ndr_xa_t *mxa) 11887961SNatalie.Li@Sun.COM { 11897961SNatalie.Li@Sun.COM struct svcctl_QueryServiceConfig2W *param = arg; 11907961SNatalie.Li@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 11917961SNatalie.Li@Sun.COM ndr_handle_t *hd; 11927961SNatalie.Li@Sun.COM svcctl_manager_context_t *mgr_ctx; 11937961SNatalie.Li@Sun.COM svcctl_service_context_t *svc_ctx; 11947961SNatalie.Li@Sun.COM svcctl_svc_node_t *svc; 119510504SKeyur.Desai@Sun.COM svc_config_rsp_t svc_rsp; 11967961SNatalie.Li@Sun.COM int offset, input_bufsize, bytes_needed = 0; 1197*10966SJordan.Brown@Sun.COM smb_wchar_t *wide_desc; 11987961SNatalie.Li@Sun.COM char *desc; 11997961SNatalie.Li@Sun.COM DWORD status; 12007961SNatalie.Li@Sun.COM 12017961SNatalie.Li@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 12027961SNatalie.Li@Sun.COM if (hd == NULL) { 12037961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); 12048334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 12057961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 12068334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12077961SNatalie.Li@Sun.COM } 12087961SNatalie.Li@Sun.COM 12097961SNatalie.Li@Sun.COM input_bufsize = param->buf_size; 12108334SJose.Borrego@Sun.COM param->buffer = NDR_MALLOC(mxa, input_bufsize); 12117961SNatalie.Li@Sun.COM if (param->buffer == NULL) { 12127961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); 12138334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 12147961SNatalie.Li@Sun.COM param->status = ERROR_NOT_ENOUGH_MEMORY; 12158334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12167961SNatalie.Li@Sun.COM } 12177961SNatalie.Li@Sun.COM bzero(param->buffer, input_bufsize); 12187961SNatalie.Li@Sun.COM 121910504SKeyur.Desai@Sun.COM svc_rsp.svc_buf = param->buffer; 12207961SNatalie.Li@Sun.COM status = ERROR_SUCCESS; 12217961SNatalie.Li@Sun.COM switch (param->info_level) { 12227961SNatalie.Li@Sun.COM case SERVICE_CONFIG_DESCRIPTION: 12237961SNatalie.Li@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 12247961SNatalie.Li@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 12257961SNatalie.Li@Sun.COM if (mgr_ctx == NULL) { 12267961SNatalie.Li@Sun.COM param->status = ERROR_INVALID_HANDLE; 12277961SNatalie.Li@Sun.COM break; 12287961SNatalie.Li@Sun.COM } 12297961SNatalie.Li@Sun.COM 12307961SNatalie.Li@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 12317961SNatalie.Li@Sun.COM if (svc == NULL || svc->sn_desc == NULL) { 12327961SNatalie.Li@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST; 12337961SNatalie.Li@Sun.COM break; 12347961SNatalie.Li@Sun.COM } 12357961SNatalie.Li@Sun.COM 12367961SNatalie.Li@Sun.COM desc = svc->sn_desc; 12377961SNatalie.Li@Sun.COM bytes_needed = SVCCTL_WNSTRLEN(desc); 12387961SNatalie.Li@Sun.COM 12397961SNatalie.Li@Sun.COM if (input_bufsize <= bytes_needed) { 12407961SNatalie.Li@Sun.COM param->bytes_needed = bytes_needed; 124110001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER; 12428334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12437961SNatalie.Li@Sun.COM } 12447961SNatalie.Li@Sun.COM 12457961SNatalie.Li@Sun.COM offset = sizeof (svc_description_t); 124610504SKeyur.Desai@Sun.COM svc_rsp.svc_desc->desc = offset; 12477961SNatalie.Li@Sun.COM /*LINTED E_BAD_PTR_CAST_ALIGN*/ 1248*10966SJordan.Brown@Sun.COM wide_desc = (smb_wchar_t *)¶m->buffer[offset]; 1249*10966SJordan.Brown@Sun.COM (void) smb_mbstowcs(wide_desc, desc, (strlen(desc) + 1)); 125010504SKeyur.Desai@Sun.COM offset += SVCCTL_WNSTRLEN(desc); 12517961SNatalie.Li@Sun.COM 12527961SNatalie.Li@Sun.COM param->bytes_needed = offset; 12537961SNatalie.Li@Sun.COM break; 12547961SNatalie.Li@Sun.COM 12557961SNatalie.Li@Sun.COM case SERVICE_CONFIG_FAILURE_ACTIONS: 125610504SKeyur.Desai@Sun.COM bzero(svc_rsp.svc_fac, sizeof (svc_failure_actions_t)); 125710504SKeyur.Desai@Sun.COM bytes_needed = sizeof (svc_failure_actions_t); 125810504SKeyur.Desai@Sun.COM if (input_bufsize <= bytes_needed) { 125910504SKeyur.Desai@Sun.COM param->bytes_needed = bytes_needed; 126010504SKeyur.Desai@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER; 126110504SKeyur.Desai@Sun.COM return (NDR_DRC_OK); 126210504SKeyur.Desai@Sun.COM } 126310504SKeyur.Desai@Sun.COM param->bytes_needed = bytes_needed; 12647961SNatalie.Li@Sun.COM break; 12657961SNatalie.Li@Sun.COM 126610504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_DELAYED_AUTO_START_INFO: 126710504SKeyur.Desai@Sun.COM svc_rsp.svc_dstart->dstart = 0; 126810504SKeyur.Desai@Sun.COM param->bytes_needed = sizeof (svc_delayed_auto_start_t); 126910504SKeyur.Desai@Sun.COM break; 127010504SKeyur.Desai@Sun.COM 127110504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_FAILURE_ACTIONS_FLAG: 127210504SKeyur.Desai@Sun.COM svc_rsp.svc_cfa->cfa = 0; 127310504SKeyur.Desai@Sun.COM param->bytes_needed = sizeof (svc_config_failure_action_t); 127410504SKeyur.Desai@Sun.COM break; 127510504SKeyur.Desai@Sun.COM 127610504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_SERVICE_SID_INFO: 127710504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO: 127810504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_PRESHUTDOWN_INFO: 127910504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_TRIGGER_INFO: 128010504SKeyur.Desai@Sun.COM case SERVICE_CONFIG_PREFERRED_NODE: 12817961SNatalie.Li@Sun.COM default: 12827961SNatalie.Li@Sun.COM status = ERROR_INVALID_LEVEL; 12837961SNatalie.Li@Sun.COM break; 12847961SNatalie.Li@Sun.COM } 12857961SNatalie.Li@Sun.COM 12867961SNatalie.Li@Sun.COM if (status != ERROR_SUCCESS) { 12877961SNatalie.Li@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceConfig2W)); 12888334SJose.Borrego@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 12897961SNatalie.Li@Sun.COM param->status = status; 12908334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12917961SNatalie.Li@Sun.COM } 12927961SNatalie.Li@Sun.COM 12937961SNatalie.Li@Sun.COM param->status = ERROR_SUCCESS; 12948334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 12957961SNatalie.Li@Sun.COM } 129610001SJoyce.McIntosh@Sun.COM 129710001SJoyce.McIntosh@Sun.COM /* 129810001SJoyce.McIntosh@Sun.COM * svcctl_s_QueryServiceStatusEx 129910001SJoyce.McIntosh@Sun.COM */ 130010001SJoyce.McIntosh@Sun.COM static int 130110001SJoyce.McIntosh@Sun.COM svcctl_s_QueryServiceStatusEx(void *arg, ndr_xa_t *mxa) 130210001SJoyce.McIntosh@Sun.COM { 130310001SJoyce.McIntosh@Sun.COM struct svcctl_QueryServiceStatusEx *param = arg; 130410001SJoyce.McIntosh@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->service_handle; 130510001SJoyce.McIntosh@Sun.COM ndr_handle_t *hd; 130610001SJoyce.McIntosh@Sun.COM svcctl_manager_context_t *mgr_ctx; 130710001SJoyce.McIntosh@Sun.COM svcctl_service_context_t *svc_ctx; 130810001SJoyce.McIntosh@Sun.COM svcctl_svc_node_t *svc; 130910001SJoyce.McIntosh@Sun.COM svc_status_ex_t *svc_status_ex; 131010001SJoyce.McIntosh@Sun.COM uint32_t input_bufsize; 131110001SJoyce.McIntosh@Sun.COM uint32_t bytes_needed; 131210001SJoyce.McIntosh@Sun.COM DWORD status; 131310001SJoyce.McIntosh@Sun.COM 131410001SJoyce.McIntosh@Sun.COM hd = svcctl_hdlookup(mxa, id, SVCCTL_SERVICE_CONTEXT); 131510001SJoyce.McIntosh@Sun.COM if (hd == NULL) { 131610001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 131710001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 131810001SJoyce.McIntosh@Sun.COM } 131910001SJoyce.McIntosh@Sun.COM 132010001SJoyce.McIntosh@Sun.COM svc_ctx = ((svcctl_context_t *)hd->nh_data)->c_ctx.uc_svc; 132110001SJoyce.McIntosh@Sun.COM mgr_ctx = svcctl_get_mgr_ctx(mxa, svc_ctx->sc_mgrid); 132210001SJoyce.McIntosh@Sun.COM if (mgr_ctx == NULL) { 132310001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_HANDLE; 132410001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 132510001SJoyce.McIntosh@Sun.COM } 132610001SJoyce.McIntosh@Sun.COM 132710001SJoyce.McIntosh@Sun.COM if (param->info_level != SC_STATUS_PROCESS_INFO) { 132810001SJoyce.McIntosh@Sun.COM status = ERROR_INVALID_PARAMETER; 132910001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 133010001SJoyce.McIntosh@Sun.COM } 133110001SJoyce.McIntosh@Sun.COM 133210504SKeyur.Desai@Sun.COM bytes_needed = sizeof (svc_status_ex_t); 133310001SJoyce.McIntosh@Sun.COM 133410001SJoyce.McIntosh@Sun.COM if ((input_bufsize = param->buf_size) < bytes_needed) { 133510001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatusEx)); 133610001SJoyce.McIntosh@Sun.COM param->buf_size = input_bufsize; 133710001SJoyce.McIntosh@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 133810001SJoyce.McIntosh@Sun.COM param->bytes_needed = bytes_needed; 133910001SJoyce.McIntosh@Sun.COM param->status = ERROR_INSUFFICIENT_BUFFER; 134010001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 134110001SJoyce.McIntosh@Sun.COM } 134210001SJoyce.McIntosh@Sun.COM 134310001SJoyce.McIntosh@Sun.COM if ((svc_status_ex = NDR_MALLOC(mxa, bytes_needed)) == NULL) { 134410001SJoyce.McIntosh@Sun.COM status = ERROR_NOT_ENOUGH_MEMORY; 134510001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 134610001SJoyce.McIntosh@Sun.COM } 134710001SJoyce.McIntosh@Sun.COM 134810001SJoyce.McIntosh@Sun.COM svc = svcctl_scm_find_service(mgr_ctx, svc_ctx->sc_svcname); 134910001SJoyce.McIntosh@Sun.COM if (svc == NULL || svc->sn_state == NULL) { 135010001SJoyce.McIntosh@Sun.COM status = ERROR_SERVICE_DOES_NOT_EXIST; 135110001SJoyce.McIntosh@Sun.COM goto query_service_status_ex_error; 135210001SJoyce.McIntosh@Sun.COM } 135310001SJoyce.McIntosh@Sun.COM 135410001SJoyce.McIntosh@Sun.COM svc_status_ex->service_type = SERVICE_WIN32_SHARE_PROCESS; 135510001SJoyce.McIntosh@Sun.COM svc_status_ex->cur_state = svcctl_scm_map_status(svc->sn_state); 135610001SJoyce.McIntosh@Sun.COM svc_status_ex->ctrl_accepted = 0; 135710001SJoyce.McIntosh@Sun.COM svc_status_ex->w32_exitcode = 0; 135810001SJoyce.McIntosh@Sun.COM svc_status_ex->svc_specified_exitcode = 0; 135910001SJoyce.McIntosh@Sun.COM svc_status_ex->check_point = 0; 136010001SJoyce.McIntosh@Sun.COM svc_status_ex->wait_hint = 0; 136110001SJoyce.McIntosh@Sun.COM svc_status_ex->process_id = 1; 136210001SJoyce.McIntosh@Sun.COM svc_status_ex->service_flags = 1; 136310001SJoyce.McIntosh@Sun.COM 136410001SJoyce.McIntosh@Sun.COM param->buffer = (uint8_t *)svc_status_ex; 136510504SKeyur.Desai@Sun.COM param->buf_size = input_bufsize; 136610504SKeyur.Desai@Sun.COM param->bytes_needed = bytes_needed; 136710001SJoyce.McIntosh@Sun.COM param->status = ERROR_SUCCESS; 136810001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 136910001SJoyce.McIntosh@Sun.COM 137010001SJoyce.McIntosh@Sun.COM query_service_status_ex_error: 137110001SJoyce.McIntosh@Sun.COM bzero(param, sizeof (struct svcctl_QueryServiceStatusEx)); 137210001SJoyce.McIntosh@Sun.COM param->buffer = NDR_STRDUP(mxa, ""); 137310001SJoyce.McIntosh@Sun.COM param->status = status; 137410001SJoyce.McIntosh@Sun.COM return (NDR_DRC_OK); 137510001SJoyce.McIntosh@Sun.COM } 1376