unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

unrealsvc.c (7759B)

      1 /************************************************************************
      2  *   IRC - Internet Relay Chat, windows/unrealsvc.c
      3  *   Copyright (C) 2002 Dominick Meglio (codemastr)
      4  *   Copyright (C) 2006-2021 Bram Matthys (Syzop)
      5  *   
      6  *   This program is free software; you can redistribute it and/or modify
      7  *   it under the terms of the GNU General Public License as published by
      8  *   the Free Software Foundation; either version 1, or (at your option)
      9  *   any later version.
     10  *
     11  *   This program is distributed in the hope that it will be useful,
     12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  *   GNU General Public License for more details.
     15  *
     16  *   You should have received a copy of the GNU General Public License
     17  *   along with this program; if not, write to the Free Software
     18  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     19  */
     20 
     21 #include "unrealircd.h"
     22 
     23 typedef BOOL (*UCHANGESERVICECONFIG2)(SC_HANDLE, DWORD, LPVOID);
     24 HMODULE hAdvapi;
     25 UCHANGESERVICECONFIG2 uChangeServiceConfig2;
     26 
     27 #define IRCD_SERVICE_CONTROL_REHASH 128
     28 void show_usage() {
     29 	fprintf(stderr, "unrealsvc start|stop|rehash|restart|install|uninstall|config <option> <value>");
     30 	fprintf(stderr, "\nValid config options:\nstartup auto|manual\n");
     31 	fprintf(stderr, "crashrestart delay\n");
     32 }
     33 
     34 char *show_error(DWORD code) {
     35 	static char buf[1024];
     36 	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, buf, 1024, NULL);
     37 	return buf;
     38 }
     39 
     40 SC_HANDLE unreal_open_service_manager(void)
     41 {
     42 	SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
     43 	if (!hSCManager)
     44 	{
     45 		printf("Failed to connect to service manager: %s", show_error(GetLastError()));
     46 		printf("Note that elevated administrator permissions are necessary to execute this command.\n");
     47 		exit(1);
     48 	}
     49 	return hSCManager;
     50 }
     51 int main(int argc, char *argv[]) {
     52 	char *bslash;
     53 
     54 	if (argc < 2) {
     55 		show_usage();
     56 		return -1;
     57 	}
     58 	hAdvapi = LoadLibrary("advapi32.dll");
     59 	uChangeServiceConfig2 = (UCHANGESERVICECONFIG2)GetProcAddress(hAdvapi, "ChangeServiceConfig2A");
     60 
     61 	if (!strcasecmp(argv[1], "install"))
     62 	{
     63 		SC_HANDLE hService, hSCManager;
     64 		char path[MAX_PATH+1];
     65 		char binpath[MAX_PATH+1];
     66 		hSCManager = unreal_open_service_manager();
     67 
     68 		GetModuleFileName(NULL,path,MAX_PATH);
     69 		if ((bslash = strrchr(path, '\\')))
     70 			*bslash = 0;
     71 		
     72 		strcpy(binpath,path);
     73 		strcat(binpath, "\\UnrealIRCd.exe");
     74 		hService = CreateService(hSCManager, "UnrealIRCd", "UnrealIRCd",
     75 				 SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS,
     76 				 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, binpath,
     77 				 NULL, NULL, NULL, TEXT("NT AUTHORITY\\NetworkService"), "");
     78 		if (hService) 
     79 		{
     80 			SERVICE_DESCRIPTION info;
     81 			printf("UnrealIRCd NT Service successfully installed\n");
     82 			info.lpDescription = "Internet Relay Chat Server. Allows users to chat with eachother via an IRC client.";
     83 			uChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &info);
     84 			CloseServiceHandle(hService);
     85 			printf("\n[!!!] IMPORTANT: By default the network service user cannot write to the \n"
     86 			       "UnrealIRCd 6 folder and this will make UnrealIRCd fail to boot without\n"
     87 				   "writing any meaningful error to the log files.\n"
     88 				   "You have two options:\n"
     89 				   "1) Manually grant FULL permissions to NT AUTHORITY\\NetworkService\n"
     90 				   "   for the UnrealIRCd 6 folder, all its subfolders and files.\n"
     91 				   "OR, easier and recommended:\n"
     92 				   "2) just re-run the UnrealIRCd installer and select 'Install as a service',\n"
     93 				   "   which sets all the necessary permissions automatically.\n");
     94 		} else {
     95 			printf("Failed to install UnrealIRCd NT Service - %s", show_error(GetLastError()));
     96 		}
     97 		CloseServiceHandle(hSCManager);
     98 		return 0;
     99 	}
    100 	else if (!strcasecmp(argv[1], "uninstall"))
    101 	{
    102 		SC_HANDLE hSCManager = unreal_open_service_manager();
    103 		SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", DELETE); 
    104 		if (DeleteService(hService)) 
    105 			printf("UnrealIRCd NT Service successfully uninstalled\n");
    106 		else
    107 			printf("Failed to uninstall UnrealIRCd NT Service - %s\n", show_error(GetLastError()));
    108 		CloseServiceHandle(hService);
    109 		CloseServiceHandle(hSCManager);
    110 		return 0;
    111 	}
    112 	else if (!strcasecmp(argv[1], "start"))
    113 	{
    114 		SC_HANDLE hSCManager = unreal_open_service_manager();
    115 		SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", SERVICE_START); 
    116 		if (StartService(hService, 0, NULL))
    117 			printf("UnrealIRCd NT Service successfully started");
    118 		else
    119 			printf("Failed to start UnrealIRCd NT Service - %s", show_error(GetLastError()));
    120 		CloseServiceHandle(hService);
    121 		CloseServiceHandle(hSCManager);
    122 		return 0;
    123 	}
    124 	else if (!strcasecmp(argv[1], "stop"))
    125 	{
    126 		SERVICE_STATUS status;
    127 		SC_HANDLE hSCManager = unreal_open_service_manager();
    128 		SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", SERVICE_STOP); 
    129 		ControlService(hService, SERVICE_CONTROL_STOP, &status);
    130 		printf("UnrealIRCd NT Service successfully stopped");
    131 		CloseServiceHandle(hService);
    132 		CloseServiceHandle(hSCManager);
    133 		return 0;
    134 	}
    135 	else if (!strcasecmp(argv[1], "restart"))
    136 	{
    137 		SERVICE_STATUS status;
    138 		SC_HANDLE hSCManager = unreal_open_service_manager();
    139 		SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", SERVICE_STOP|SERVICE_START); 
    140 		ControlService(hService, SERVICE_CONTROL_STOP, &status);
    141 		if (StartService(hService, 0, NULL)) 
    142 			printf("UnrealIRCd NT Service successfully restarted");
    143 		CloseServiceHandle(hService);
    144 		CloseServiceHandle(hSCManager);
    145 		return 0;
    146 	}
    147 	else if (!strcasecmp(argv[1], "rehash"))
    148 	{
    149 		SERVICE_STATUS status;
    150 		SC_HANDLE hSCManager = unreal_open_service_manager();
    151 		SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", SERVICE_USER_DEFINED_CONTROL); 
    152 		ControlService(hService, IRCD_SERVICE_CONTROL_REHASH, &status);
    153 		printf("UnrealIRCd NT Service successfully rehashed");
    154 	}
    155 	else if (!strcasecmp(argv[1], "config"))
    156 	{
    157 		SERVICE_STATUS status;
    158 		SC_HANDLE hSCManager = unreal_open_service_manager();
    159 		SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", SERVICE_CHANGE_CONFIG|SERVICE_START);
    160 		if (argc < 3) {
    161 			show_usage();
    162 			return -1;
    163 		}
    164 		if (!strcasecmp(argv[2], "startup")) {
    165 			if (ChangeServiceConfig(hService, SERVICE_NO_CHANGE,
    166 					    !strcasecmp(argv[3], "auto") ? SERVICE_AUTO_START
    167 						: SERVICE_DEMAND_START, SERVICE_NO_CHANGE,
    168 					    NULL, NULL, NULL, NULL, NULL, NULL, NULL)) 
    169 				printf("UnrealIRCd NT Service configuration changed");
    170 			else
    171 				printf("UnrealIRCd NT Service configuration change failed - %s", show_error(GetLastError()));	
    172 		}
    173 		else if (!strcasecmp(argv[2], "crashrestart")) {
    174 			SERVICE_FAILURE_ACTIONS hFailActions;
    175 			SC_ACTION hAction;
    176 			memset(&hFailActions, 0, sizeof(hFailActions));
    177 			if (argc >= 4) {
    178 				hFailActions.dwResetPeriod = 30;
    179 				hFailActions.cActions = 1;
    180 				hAction.Type = SC_ACTION_RESTART;
    181 				hAction.Delay = atoi(argv[3])*60000;
    182 				hFailActions.lpsaActions = &hAction;
    183 				if (uChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, 	
    184 						     &hFailActions))
    185 					printf("UnrealIRCd NT Service configuration changed");
    186 				else
    187 					printf("UnrealIRCd NT Service configuration change failed - %s", show_error(GetLastError()));	
    188 			}
    189 			else {
    190 				hFailActions.dwResetPeriod = 0;
    191 				hFailActions.cActions = 0;
    192 				hAction.Type = SC_ACTION_NONE;
    193 				hFailActions.lpsaActions = &hAction;
    194 				if (uChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS,
    195 						     &hFailActions)) 
    196 					printf("UnrealIRCd NT Service configuration changed");
    197 				else
    198 					printf("UnrealIRCd NT Service configuration change failed - %s", show_error(GetLastError()));	
    199 
    200 				
    201 			}
    202 		}
    203 		else {
    204 			show_usage();
    205 			return -1;
    206 		}	
    207 	}
    208 	else {
    209 		show_usage();
    210 		return -1;
    211 	}
    212 }
    213