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