1 /* netuser.c - LOGIN/LOGOUT/USERNAME/PASSWORD/MASTER[PRIMARY] handlers for upsd
2 
3    Copyright (C) 2003  Russell Kroll <rkroll@exploits.org>
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 
20 #include "common.h"
21 
22 #include "upsd.h"
23 #include "sstate.h"
24 #include "state.h"
25 #include "neterr.h"
26 #include "user.h"		/* for user_checkaction */
27 
28 #include "netuser.h"
29 
30 /* LOGIN <ups> */
net_login(nut_ctype_t * client,size_t numarg,const char ** arg)31 void net_login(nut_ctype_t *client, size_t numarg, const char **arg)
32 {
33 	upstype_t	*ups;
34 
35 	if (numarg != 1) {
36 		send_err(client, NUT_ERR_INVALID_ARGUMENT);
37 		return;
38 	}
39 
40 	if (client->loginups != NULL) {
41 		upslogx(LOG_INFO, "Client %s@%s tried to login twice", client->username, client->addr);
42 		send_err(client, NUT_ERR_ALREADY_LOGGED_IN);
43 		return;
44 	}
45 
46 	/* make sure we got a valid UPS name */
47 	ups = get_ups_ptr(arg[0]);
48 
49 	if (!ups) {
50 		send_err(client, NUT_ERR_UNKNOWN_UPS);
51 		return;
52 	}
53 
54 	/* make sure this is a valid user */
55 	if (!user_checkaction(client->username, client->password, "LOGIN")) {
56 		send_err(client, NUT_ERR_ACCESS_DENIED);
57 		return;
58 	}
59 
60 	ups->numlogins++;
61 	client->loginups = xstrdup(ups->name);
62 
63 	upslogx(LOG_INFO, "User %s@%s logged into UPS [%s]%s", client->username, client->addr,
64 		client->loginups, client->ssl ? " (SSL)" : "");
65 	sendback(client, "OK\n");
66 }
67 
net_logout(nut_ctype_t * client,size_t numarg,const char ** arg)68 void net_logout(nut_ctype_t *client, size_t numarg, const char **arg)
69 {
70 	NUT_UNUSED_VARIABLE(arg);
71 	if (numarg != 0) {
72 		send_err(client, NUT_ERR_INVALID_ARGUMENT);
73 		return;
74 	}
75 
76 	if (client->loginups != NULL) {
77 		upslogx(LOG_INFO, "User %s@%s logged out from UPS [%s]%s", client->username, client->addr,
78 			client->loginups, client->ssl ? " (SSL)" : "");
79 	}
80 
81 	sendback(client, "OK Goodbye\n");
82 
83 	client->last_heard = 0;
84 }
85 
86 /* MASTER <upsname> */
87 /* FIXME: Protocol update needed to handle master/primary alias
88  * and probably an API bump also, to rename/alias the routine.
89  */
net_master(nut_ctype_t * client,size_t numarg,const char ** arg)90 void net_master(nut_ctype_t *client, size_t numarg, const char **arg)
91 {
92 	upstype_t	*ups;
93 
94 	if (numarg != 1) {
95 		send_err(client, NUT_ERR_INVALID_ARGUMENT);
96 		return;
97 	}
98 
99 	ups = get_ups_ptr(arg[0]);
100 
101 	if (!ups) {
102 		send_err(client, NUT_ERR_UNKNOWN_UPS);
103 		return;
104 	}
105 
106 	/* make sure this user is allowed to do MASTER */
107 	if (!user_checkaction(client->username, client->password, "MASTER")) {
108 		send_err(client, NUT_ERR_ACCESS_DENIED);
109 		return;
110 	}
111 
112 	/* this is just an access level check */
113 	sendback(client, "OK MASTER-GRANTED\n");
114 }
115 
116 /* USERNAME <username> */
net_username(nut_ctype_t * client,size_t numarg,const char ** arg)117 void net_username(nut_ctype_t *client, size_t numarg, const char **arg)
118 {
119 	if (numarg != 1) {
120 		send_err(client, NUT_ERR_INVALID_ARGUMENT);
121 		return;
122 	}
123 
124 	if (client->username != NULL) {
125 		upslogx(LOG_INFO, "Client %s@%s tried to set a username twice",
126 			client->username, client->addr);
127 
128 		send_err(client, NUT_ERR_ALREADY_SET_USERNAME);
129 		return;
130 	}
131 
132 	client->username = xstrdup(arg[0]);
133 	sendback(client, "OK\n");
134 }
135 
136 /* PASSWORD <password> */
net_password(nut_ctype_t * client,size_t numarg,const char ** arg)137 void net_password(nut_ctype_t *client, size_t numarg, const char **arg)
138 {
139 	if (numarg != 1) {
140 		send_err(client, NUT_ERR_INVALID_ARGUMENT);
141 		return;
142 	}
143 
144 	if (client->password != NULL) {
145 		if (client->username)
146 			upslogx(LOG_INFO, "Client %s@%s tried to set a password twice",
147 				client->username, client->addr);
148 		else
149 			upslogx(LOG_INFO, "Client on %s tried to set a password twice",
150 				client->addr);
151 
152 		send_err(client, NUT_ERR_ALREADY_SET_PASSWORD);
153 		return;
154 	}
155 
156 	client->password = xstrdup(arg[0]);
157 	sendback(client, "OK\n");
158 }
159