unrealircd

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

svso.c (3580B)

      1 /* src/modules/svso.c - Grant IRCOp rights (for Services)
      2  * (C) Copyright 2022 Bram Matthys (Syzop) and the UnrealIRCd team
      3  * License: GPLv2 or later
      4  */
      5 #include "unrealircd.h"
      6 
      7 ModuleHeader MOD_HEADER
      8 = {
      9 	"svso",
     10 	"6.0.0",
     11 	"Grant oper privileges via SVSO services command",
     12 	"UnrealIRCd Team",
     13 	"unrealircd-6",
     14 };
     15 
     16 /* Forward declarations */
     17 CMD_FUNC(cmd_svso);
     18 
     19 MOD_INIT()
     20 {
     21 	MARK_AS_OFFICIAL_MODULE(modinfo);
     22 
     23 	CommandAdd(modinfo->handle, "SVSO", cmd_svso, MAXPARA, CMD_USER|CMD_SERVER);
     24 	return MOD_SUCCESS;
     25 }
     26 
     27 MOD_LOAD()
     28 {
     29 	return MOD_SUCCESS;
     30 }
     31 
     32 MOD_UNLOAD()
     33 {
     34 	return MOD_SUCCESS;
     35 }
     36 
     37 /* Syntax: SVSO <uid|nick> <oper account> <operclass> <class> <modes> <snomask> <vhost>
     38  * All these parameters need to be set, you cannot leave any of them out,
     39  * HOWEVER some can be set to "-" to skip setting them, this is true for:
     40  * <class>, <modes>, <snomask>, <vhost>
     41  *
     42  * In UnrealIRCd the <operclass> will be prefixed by "services:" if not already
     43  * present. It is up to you to include or omit it.
     44  */
     45 CMD_FUNC(cmd_svso)
     46 {
     47 	Client *acptr;
     48 	char oper_account[64];
     49 	const char *operclass;
     50 	const char *clientclass;
     51 	ConfigItem_class *clientclass_c;
     52 	const char *modes;
     53 	long modes_i = 0;
     54 	const char *snomask;
     55 	const char *vhost;
     56 
     57 	if (!IsSvsCmdOk(client))
     58 		return;
     59 
     60 	if ((parc < 8) || BadPtr(parv[7]))
     61 	{
     62 		sendnumeric(client, ERR_NEEDMOREPARAMS, "SVSO");
     63 		return;
     64 	}
     65 
     66 	operclass = parv[3];
     67 	clientclass = parv[4];
     68 	modes = parv[5];
     69 	snomask = parv[6];
     70 	vhost = parv[7];
     71 
     72 	acptr = find_user(parv[1], NULL);
     73 	if (!acptr)
     74 	{
     75 		sendnumeric(client, ERR_NOSUCHNICK, parv[1]);
     76 		return;
     77 	}
     78 
     79 	if (!MyUser(acptr))
     80 	{
     81 		/* Forward it to the correct server, and we are done... */
     82 		sendto_one(acptr, recv_mtags, ":%s SVSO %s %s %s %s %s %s %s",
     83 		           client->name, acptr->id, parv[2], parv[3], parv[4], parv[5], parv[6], parv[7]);
     84 		return;
     85 	}
     86 
     87 	/* CAVEAT ALERT !
     88 	 * Don't mix up 'client' and 'acptr' below...
     89 	 * 'client' is the server or services pseudouser that requests the change
     90 	 * 'acptr' is the person that will be made OPER
     91 	 */
     92 
     93 	/* If we get here, we validate the request and then make the user oper. */
     94 	if (!find_operclass(operclass))
     95 	{
     96 		sendnumeric(client, ERR_CANNOTDOCOMMAND, "SVSO", "Operclass does not exist");
     97 		return;
     98 	}
     99 
    100 	/* Set any items to NULL if they are skipped (on request) */
    101 	if (!strcmp(clientclass, "-"))
    102 		clientclass = NULL;
    103 	if (!strcmp(modes, "-"))
    104 		modes = NULL;
    105 	if (!strcmp(snomask, "-"))
    106 		snomask = NULL;
    107 	if (!strcmp(vhost, "-"))
    108 		vhost = NULL;
    109 
    110 	/* First, maybe the user is oper already? Then de-oper them.. */
    111 	if (IsOper(acptr))
    112 	{
    113 		int was_hidden_oper = IsHideOper(acptr) ? 1 : 0;
    114 
    115 		list_del(&acptr->special_node);
    116 		RunHook(HOOKTYPE_LOCAL_OPER, acptr, 0, NULL, NULL);
    117 		remove_oper_privileges(acptr, 1);
    118 
    119 		if (!was_hidden_oper)
    120 			irccounts.operators--;
    121 		VERIFY_OPERCOUNT(acptr, "svso");
    122 
    123 	}
    124 
    125 	if (vhost && !valid_vhost(vhost))
    126 		sendnumeric(client, ERR_CANNOTDOCOMMAND, "SVSO", "Failed to make user oper: vhost contains illegal characters or is too long");
    127 
    128 	/* Prefix the oper block name with "remote:" if it hasn't already */
    129 	if (!strncmp(parv[2], "remote:", 7))
    130 		strlcpy(oper_account, parv[2], sizeof(oper_account));
    131 	else
    132 		snprintf(oper_account, sizeof(oper_account), "remote:%s", parv[2]);
    133 
    134 	/* These needs to be looked up... */
    135 	clientclass_c = find_class(clientclass); /* NULL is fine! */
    136 	if (modes)
    137 		modes_i = set_usermode(modes);
    138 
    139 	if (!make_oper(acptr, oper_account, operclass, clientclass_c, modes_i, snomask, vhost))
    140 		sendnumeric(client, ERR_CANNOTDOCOMMAND, "SVSO", "Failed to make user oper");
    141 }