1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
5    Copyright (C) 2011-2012 Planets Communications B.V.
6    Copyright (C) 2013-2016 Bareos GmbH & Co. KG
7 
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    Affero General Public License for more details.
17 
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22 */
23 /*
24  * Kern Sibbald, September MM
25  */
26 /**
27  * @file
28  * User Agent Server
29  */
30 
31 #include "include/bareos.h"
32 #include "dird.h"
33 #include "dird/dird_globals.h"
34 #include "dird/authenticate.h"
35 #include "dird/authenticate_console.h"
36 #include "dird/jcr_private.h"
37 #include "dird/job.h"
38 #include "dird/pthread_detach_if_not_detached.h"
39 #include "dird/ua_cmds.h"
40 #include "dird/ua_db.h"
41 #include "dird/ua_input.h"
42 #include "dird/ua_output.h"
43 #include "dird/ua_server.h"
44 #include "lib/bnet.h"
45 #include "lib/parse_conf.h"
46 #include "lib/thread_specific_data.h"
47 
48 
49 namespace directordaemon {
50 
51 /**
52  * Create a Job Control Record for a control "job", filling in all the
53  * appropriate fields.
54  */
new_control_jcr(const char * base_name,int job_type)55 JobControlRecord* new_control_jcr(const char* base_name, int job_type)
56 {
57   JobControlRecord* jcr;
58 
59   jcr = NewDirectorJcr();
60 
61   /*
62    * The job and defaults are not really used, but we set them up to ensure that
63    * everything is correctly initialized.
64    */
65   LockRes(my_config);
66   jcr->impl->res.job = (JobResource*)my_config->GetNextRes(R_JOB, NULL);
67   SetJcrDefaults(jcr, jcr->impl->res.job);
68   UnlockRes(my_config);
69 
70   jcr->sd_auth_key = strdup("dummy"); /* dummy Storage daemon key */
71   CreateUniqueJobName(jcr, base_name);
72   jcr->sched_time = jcr->start_time;
73   jcr->setJobType(job_type);
74   jcr->setJobLevel(L_NONE);
75   jcr->setJobStatus(JS_Running);
76   jcr->JobId = 0;
77 
78   return jcr;
79 }
80 
81 /**
82  * Handle Director User Agent commands
83  */
HandleUserAgentClientRequest(BareosSocket * user_agent_socket)84 void* HandleUserAgentClientRequest(BareosSocket* user_agent_socket)
85 {
86   DetachIfNotDetached(pthread_self());
87 
88   JobControlRecord* jcr = new_control_jcr("-Console-", JT_CONSOLE);
89 
90   UaContext* ua = new_ua_context(jcr);
91   ua->UA_sock = user_agent_socket;
92   SetJcrInThreadSpecificData(nullptr);
93 
94   bool success = AuthenticateConsole(ua);
95 
96   if (!success) { ua->quit = true; }
97 
98   while (!ua->quit) {
99     if (ua->api) { user_agent_socket->signal(BNET_MAIN_PROMPT); }
100 
101     int status = user_agent_socket->recv();
102     if (status >= 0) {
103       PmStrcpy(ua->cmd, ua->UA_sock->msg);
104       ParseUaArgs(ua);
105       Do_a_command(ua);
106 
107       DequeueMessages(ua->jcr);
108 
109       if (!ua->quit) {
110         if (console_msg_pending && ua->AclAccessOk(Command_ACL, "messages")) {
111           if (ua->auto_display_messages) {
112             PmStrcpy(ua->cmd, "messages");
113             DotMessagesCmd(ua, ua->cmd);
114             ua->user_notified_msg_pending = false;
115           } else if (!ua->gui && !ua->user_notified_msg_pending &&
116                      console_msg_pending) {
117             if (ua->api) {
118               user_agent_socket->signal(BNET_MSGS_PENDING);
119             } else {
120               bsendmsg(ua, _("You have messages.\n"));
121             }
122             ua->user_notified_msg_pending = true;
123           }
124         }
125         if (!ua->api) {
126           user_agent_socket->signal(BNET_EOD); /* send end of command */
127         }
128       }
129     } else if (IsBnetStop(user_agent_socket)) {
130       ua->quit = true;
131     } else { /* signal */
132       user_agent_socket->signal(BNET_POLL);
133     }
134   } /* while (!ua->quit) */
135 
136   CloseDb(ua);
137   FreeUaContext(ua);
138   FreeJcr(jcr);
139   delete user_agent_socket;
140 
141   return NULL;
142 }
143 } /* namespace directordaemon */
144