bool svcctl_init_winreg(struct messaging_context *msg_ctx) { struct dcerpc_binding_handle *h = NULL; uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; struct policy_handle hive_hnd, key_hnd; const char **service_list = lp_svcctl_list(); const char **subkeys = NULL; uint32_t num_subkeys = 0; char *key = NULL; uint32_t i; NTSTATUS status; WERROR result = WERR_OK; bool ok = false; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_stackframe(); if (tmp_ctx == NULL) { return false; } DEBUG(3, ("Initialise the svcctl registry keys if needed.\n")); ZERO_STRUCT(hive_hnd); ZERO_STRUCT(key_hnd); key = talloc_strdup(tmp_ctx, TOP_LEVEL_SERVICES_KEY); if (key == NULL) { goto done; } result = regdb_open(); if (!W_ERROR_IS_OK(result)) { DEBUG(10, ("regdb_open failed: %s\n", win_errstr(result))); goto done; } result = regdb_transaction_start(); if (!W_ERROR_IS_OK(result)) { DEBUG(10, ("regdb_transaction_start failed: %s\n", win_errstr(result))); goto done; } status = dcerpc_winreg_int_hklm_openkey(tmp_ctx, get_session_info_system(), msg_ctx, &h, key, false, access_mask, &hive_hnd, &key_hnd, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg: Could not open %s - %s\n", key, nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg: Could not open %s - %s\n", key, win_errstr(result))); goto done; } /* get all subkeys */ status = dcerpc_winreg_enum_keys(tmp_ctx, h, &key_hnd, &num_subkeys, &subkeys, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg: Could enum keys at %s - %s\n", key, nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg: Could enum keys at %s - %s\n", key, win_errstr(result))); goto done; } for (i = 0; builtin_svcs[i].servicename != NULL; i++) { uint32_t j; bool skip = false; for (j = 0; j < num_subkeys; j++) { if (strequal(subkeys[i], builtin_svcs[i].servicename)) { skip = true; } } if (skip) { continue; } ok = svcctl_add_service(tmp_ctx, h, &hive_hnd, key, access_mask, builtin_svcs[i].servicename); if (!ok) { goto done; } } for (i = 0; service_list && service_list[i]; i++) { uint32_t j; bool skip = false; for (j = 0; j < num_subkeys; j++) { if (strequal(subkeys[i], service_list[i])) { skip = true; } } if (skip) { continue; } ok = svcctl_add_service(tmp_ctx, h, &hive_hnd, key, access_mask, service_list[i]); if (is_valid_policy_hnd(&key_hnd)) { dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result); } ZERO_STRUCT(key_hnd); if (!ok) { goto done; } } done: if (is_valid_policy_hnd(&key_hnd)) { dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result); } if (ok) { result = regdb_transaction_commit(); if (!W_ERROR_IS_OK(result)) { DEBUG(10, ("regdb_transaction_commit failed: %s\n", win_errstr(result))); } } else { result = regdb_transaction_cancel(); if (!W_ERROR_IS_OK(result)) { DEBUG(10, ("regdb_transaction_cancel failed: %s\n", win_errstr(result))); } } regdb_close(); talloc_free(tmp_ctx); return ok; }
static bool sync_eventlog_params(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, EVENTLOG_INFO *info) { struct dcerpc_binding_handle *h = NULL; uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; struct policy_handle hive_hnd, key_hnd; uint32_t uiMaxSize = 0; uint32_t uiRetention = 0; char *path = NULL; NTSTATUS status; WERROR wresult = WERR_OK; char *elogname = info->logname; TALLOC_CTX *ctx; bool ret = false; ctx = talloc_stackframe(); if (ctx == NULL) { return false; } DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) ); if ( !info->etdb ) { DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) ); goto done; } /* set resonable defaults. 512Kb on size and 1 week on time */ uiMaxSize = 0x80000; uiRetention = 604800; /* the general idea is to internally open the registry key and retrieve the values. That way we can continue to use the same fetch/store api that we use in srv_reg_nt.c */ path = talloc_asprintf(ctx, "%s\\%s", TOP_LEVEL_EVENTLOG_KEY, elogname); if (!path) { goto done; } status = dcerpc_winreg_int_hklm_openkey(ctx, get_session_info_system(), msg_ctx, &h, path, false, access_mask, &hive_hnd, &key_hnd, &wresult); if (!NT_STATUS_IS_OK(status)) { DEBUG(4,("sync_eventlog_params: Failed to open key [%s] (%s)\n", path, nt_errstr(status))); goto done; } if ( !W_ERROR_IS_OK( wresult ) ) { DEBUG( 4, ( "sync_eventlog_params: Failed to open key [%s] (%s)\n", path, win_errstr( wresult ) ) ); goto done; } status = dcerpc_winreg_query_dword(ctx, h, &key_hnd, "Retention", &uiRetention, &wresult); if (!NT_STATUS_IS_OK(status)) { DEBUG(4, ("Failed to query value \"Retention\": %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(wresult)) { DEBUG(4, ("Failed to query value \"Retention\": %s\n", win_errstr(wresult))); goto done; } status = dcerpc_winreg_query_dword(ctx, h, &key_hnd, "MaxSize", &uiMaxSize, &wresult); if (!NT_STATUS_IS_OK(status)) { DEBUG(4, ("Failed to query value \"Retention\": %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(wresult)) { DEBUG(4, ("Failed to query value \"MaxSize\": %s\n", win_errstr(wresult))); goto done; } tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize ); tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention ); ret = true; done: if (h != NULL) { WERROR ignore; if (is_valid_policy_hnd(&key_hnd)) { dcerpc_winreg_CloseKey(h, ctx, &key_hnd, &ignore); } if (is_valid_policy_hnd(&hive_hnd)) { dcerpc_winreg_CloseKey(h, ctx, &hive_hnd, &ignore); } } TALLOC_FREE(ctx); return ret; }
static bool svcctl_add_service(TALLOC_CTX *mem_ctx, struct dcerpc_binding_handle *h, struct policy_handle *hive_hnd, const char *key, uint32_t access_mask, const char *name) { enum winreg_CreateAction action = REG_ACTION_NONE; struct security_descriptor *sd = NULL; struct policy_handle key_hnd; struct winreg_String wkey; struct winreg_String wkeyclass; char *description = NULL; char *dname = NULL; char *ipath = NULL; bool ok = false; uint32_t i; NTSTATUS status; WERROR result = WERR_OK; ZERO_STRUCT(key_hnd); ZERO_STRUCT(wkey); wkey.name = talloc_asprintf(mem_ctx, "%s\\%s", key, name); if (wkey.name == NULL) { goto done; } ZERO_STRUCT(wkeyclass); wkeyclass.name = ""; status = dcerpc_winreg_CreateKey(h, mem_ctx, hive_hnd, wkey, wkeyclass, 0, access_mask, NULL, &key_hnd, &action, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n", wkey.name, nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n", wkey.name, win_errstr(result))); goto done; } /* These values are hardcoded in all QueryServiceConfig() replies. I'm just storing them here for cosmetic purposes */ status = dcerpc_winreg_set_dword(mem_ctx, h, &key_hnd, "Start", SVCCTL_AUTO_START, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", win_errstr(result))); goto done; } status = dcerpc_winreg_set_dword(mem_ctx, h, &key_hnd, "Type", SERVICE_TYPE_WIN32_OWN_PROCESS, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", win_errstr(result))); goto done; } status = dcerpc_winreg_set_dword(mem_ctx, h, &key_hnd, "ErrorControl", SVCCTL_SVC_ERROR_NORMAL, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", win_errstr(result))); goto done; } status = dcerpc_winreg_set_sz(mem_ctx, h, &key_hnd, "ObjectName", "LocalSystem", &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", win_errstr(result))); goto done; } /* * Special considerations for internal services and the DisplayName * value. */ for (i = 0; builtin_svcs[i].servicename; i++) { if (strequal(name, builtin_svcs[i].servicename)) { ipath = talloc_asprintf(mem_ctx, "%s/%s/%s", get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, builtin_svcs[i].daemon); description = talloc_strdup(mem_ctx, builtin_svcs[i].description); dname = talloc_strdup(mem_ctx, builtin_svcs[i].dispname); break; } } /* Default to an external service if we haven't found a match */ if (builtin_svcs[i].servicename == NULL) { struct rcinit_file_information *init_info = NULL; char *dispname = NULL; ipath = talloc_asprintf(mem_ctx, "%s/%s/%s", get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, name); /* lookup common unix display names */ dispname = svcctl_get_common_service_dispname(mem_ctx, name); dname = talloc_strdup(mem_ctx, dispname ? dispname : ""); /* get info from init file itself */ if (read_init_file(mem_ctx, name, &init_info)) { description = talloc_strdup(mem_ctx, init_info->description); } else { description = talloc_strdup(mem_ctx, "External Unix Service"); } } if (ipath == NULL || dname == NULL || description == NULL) { goto done; } status = dcerpc_winreg_set_sz(mem_ctx, h, &key_hnd, "DisplayName", dname, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", win_errstr(result))); goto done; } status = dcerpc_winreg_set_sz(mem_ctx, h, &key_hnd, "ImagePath", ipath, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", win_errstr(result))); goto done; } status = dcerpc_winreg_set_sz(mem_ctx, h, &key_hnd, "Description", description, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", win_errstr(result))); goto done; } sd = svcctl_gen_service_sd(mem_ctx); if (sd == NULL) { DEBUG(0, ("add_new_svc_name: Failed to create default " "sec_desc!\n")); goto done; } if (is_valid_policy_hnd(&key_hnd)) { dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &result); } ZERO_STRUCT(key_hnd); ZERO_STRUCT(wkey); wkey.name = talloc_asprintf(mem_ctx, "%s\\%s\\Security", key, name); if (wkey.name == NULL) { result = WERR_NOMEM; goto done; } ZERO_STRUCT(wkeyclass); wkeyclass.name = ""; status = dcerpc_winreg_CreateKey(h, mem_ctx, hive_hnd, wkey, wkeyclass, 0, access_mask, NULL, &key_hnd, &action, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n", wkey.name, nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n", wkey.name, win_errstr(result))); goto done; } status = dcerpc_winreg_set_sd(mem_ctx, h, &key_hnd, "Security", sd, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n", win_errstr(result))); goto done; } ok = true; done: if (is_valid_policy_hnd(&key_hnd)) { dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &result); } return ok; }
bool svcctl_set_secdesc(struct messaging_context *msg_ctx, const struct auth_session_info *session_info, const char *name, struct security_descriptor *sd) { struct dcerpc_binding_handle *h = NULL; uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; struct policy_handle hive_hnd; struct policy_handle key_hnd = { 0, }; char *key = NULL; bool ok = false; TALLOC_CTX *tmp_ctx; NTSTATUS status; WERROR result = WERR_OK; tmp_ctx = talloc_stackframe(); if (tmp_ctx == NULL) { return false; } key = talloc_asprintf(tmp_ctx, "%s\\%s", TOP_LEVEL_SERVICES_KEY, name); if (key == NULL) { goto done; } status = dcerpc_winreg_int_hklm_openkey(tmp_ctx, session_info, msg_ctx, &h, key, false, access_mask, &hive_hnd, &key_hnd, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n", key, nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n", key, win_errstr(result))); goto done; } if (is_valid_policy_hnd(&key_hnd)) { dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result); } { enum winreg_CreateAction action = REG_ACTION_NONE; struct winreg_String wkey = { 0, }; struct winreg_String wkeyclass; wkey.name = talloc_asprintf(tmp_ctx, "%s\\Security", key); if (wkey.name == NULL) { result = WERR_NOT_ENOUGH_MEMORY; goto done; } ZERO_STRUCT(wkeyclass); wkeyclass.name = ""; status = dcerpc_winreg_CreateKey(h, tmp_ctx, &hive_hnd, wkey, wkeyclass, 0, access_mask, NULL, &key_hnd, &action, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n", wkey.name, nt_errstr(status))); goto done; } if (!W_ERROR_IS_OK(result)) { DEBUG(2, ("svcctl_set_secdesc: Could not create key %s: %s\n", wkey.name, win_errstr(result))); goto done; } status = dcerpc_winreg_set_sd(tmp_ctx, h, &key_hnd, "Security", sd, &result); if (!NT_STATUS_IS_OK(status)) { goto done; } if (!W_ERROR_IS_OK(result)) { goto done; } } ok = true; done: if (is_valid_policy_hnd(&key_hnd)) { dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result); } talloc_free(tmp_ctx); return ok; }