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 }