]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/hello.c
87a31ba5e4e98233286e532827ef16c12d44a72f
[bacula/bacula] / bacula / src / filed / hello.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2016 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  * Authenticate Director who is attempting to connect.
21  *
22  *   Kern Sibbald, October 2000
23  *
24  */
25
26 #include "bacula.h"
27 #include "filed.h"
28
29 extern CLIENT *me;                 /* my resource */
30
31 const int dbglvl = 50;
32
33 /* FD_VERSION history
34  *   None prior to 10Mar08
35  *   1 10Mar08
36  *   2 13Mar09 - added the ability to restore from multiple storages
37  *   3 03Sep10 - added the restore object command
38  *   4 25Nov10 - added bandwidth command 5.1
39  *   5 24Nov11 - added new restore object command format (pluginname)
40  *   6 15Feb12 - added Component selection information list
41  *   7 19Feb12 - added Expected files to restore
42  *   8 22Mar13 - added restore options + version for SD
43  *   9 06Aug13 - skipped
44  *  10 01Jan14 - added SD Calls Client
45  *  11 O4May14 - skipped
46  *  12 22Jun14 - skipped
47  * 213 04Feb15 - added snapshot protocol with the DIR
48  */
49
50 #define FD_VERSION 213 /* FD version */
51
52 static char hello_sd[]  = "Hello Bacula SD: Start Job %s %d\n";
53 static char hello_dir[] = "2000 OK Hello %d\n";
54 static char sorry_dir[] = "2999 Authentication failed.\n";
55
56 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
57
58 /*********************************************************************
59  *
60  * Validate hello from the Director
61  *
62  * Returns: true  if Hello is good.
63  *          false if Hello is bad.
64  */
65 bool validate_dir_hello(JCR *jcr)
66 {
67    POOLMEM *dirname;
68    DIRRES *director = NULL;
69    int dir_version = 0;
70    BSOCK *dir = jcr->dir_bsock;
71    bool auth_success = false;
72
73    if (dir->msglen < 25 || dir->msglen > 500) {
74       Dmsg2(dbglvl, "Bad Hello command from Director at %s. Len=%d.\n",
75             dir->who(), dir->msglen);
76       Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
77             dir->who(), dir->msglen);
78       return false;
79    }
80    dirname = get_pool_memory(PM_MESSAGE);
81    dirname = check_pool_memory_size(dirname, dir->msglen);
82
83    if (sscanf(dir->msg, "Hello Director %127s calling %d", dirname, &dir_version) != 2 &&
84        sscanf(dir->msg, "Hello Director %127s calling", dirname) != 1) {
85       char addr[64];
86       char *who = dir->get_peer(addr, sizeof(addr)) ? dir->who() : addr;
87       dir->msg[100] = 0;
88       Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n",
89             dir->who(), dir->msg);
90       Jmsg2(jcr, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
91             who, dir->msg);
92       goto auth_fatal;
93    }
94    unbash_spaces(dirname);
95    foreach_res(director, R_DIRECTOR) {
96       if (strcmp(director->hdr.name, dirname) == 0)
97          break;
98    }
99    if (!director) {
100       char addr[64];
101       char *who = dir->get_peer(addr, sizeof(addr)) ? dir->who() : addr;
102       Jmsg2(jcr, M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"),
103             dirname, who);
104       goto auth_fatal;
105    }
106    auth_success = true;
107
108 auth_fatal:
109    free_pool_memory(dirname);
110    jcr->director = director;
111    /* Single thread all failures to avoid DOS */
112    if (!auth_success) {
113       P(mutex);
114       bmicrosleep(6, 0);
115       V(mutex);
116    }
117    return auth_success;
118 }
119
120 /*
121  * Note, we handle the initial connection request here.
122  *   We only get the jobname and the SD version, then we
123  *   return, authentication will be done when the Director
124  *   sends the storage command -- as is usually the case.
125  *   This should be called only once by the SD.
126  */
127 void *handle_storage_connection(BSOCK *sd)
128 {
129    char job_name[500];
130    char tbuf[150];
131    int sd_version = 0;
132    JCR *jcr;
133
134    if (sscanf(sd->msg, "Hello FD: Bacula Storage calling Start Job %127s %d",
135        job_name, &sd_version) != 2) {
136       Jmsg(NULL, M_FATAL, 0, _("SD connect failed: Bad Hello command\n"));
137       return NULL;
138    }
139    Dmsg1(110, "Got a SD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf),
140          (utime_t)time(NULL)));
141    Dmsg1(50, "%s", sd->msg);
142
143    if (!(jcr=get_jcr_by_full_name(job_name))) {
144       Jmsg1(NULL, M_FATAL, 0, _("SD connect failed: Job name not found: %s\n"), job_name);
145       Dmsg1(3, "**** Job \"%s\" not found.\n", job_name);
146       sd->destroy();
147       return NULL;
148    }
149    set_jcr_in_tsd(jcr);
150    Dmsg1(150, "Found Job %s\n", job_name);
151
152    jcr->lock_auth();
153    /* We already have a socket connected, just discard it */
154    if (jcr->sd_calls_client_bsock) {
155       Qmsg1(jcr, M_WARNING, 0, _("SD \"%s\" tried to connect two times.\n"), sd->who());
156       free_bsock(sd);
157       /* will exit just after the unlock() */
158
159    } else {
160       /* If we have a previous socket in store_bsock, we are in multi restore mode */
161       jcr->sd_calls_client_bsock = sd;
162       sd->set_jcr(jcr);
163    }
164    jcr->unlock_auth();
165
166    if (!sd) {                   /* freed by free_bsock(), connection already done */
167       free_jcr(jcr);
168       return NULL;
169    }
170
171    if (!jcr->max_bandwidth) {
172       if (jcr->director->max_bandwidth_per_job) {
173          jcr->max_bandwidth = jcr->director->max_bandwidth_per_job;
174
175       } else if (me->max_bandwidth_per_job) {
176          jcr->max_bandwidth = me->max_bandwidth_per_job;
177       }
178    }
179    sd->set_bwlimit(jcr->max_bandwidth);
180
181    pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
182    free_jcr(jcr);
183    return NULL;
184 }
185
186
187 /*
188  * Send Hello OK to DIR
189  */
190 bool send_hello_ok(BSOCK *bs)
191 {
192    return bs->fsend(hello_dir, FD_VERSION);
193 }
194
195 bool send_sorry(BSOCK *bs)
196 {
197    return bs->fsend(sorry_dir);
198 }
199
200 /*
201  * Send Hello to SD
202  */
203 bool send_hello_sd(JCR *jcr, char *Job)
204 {
205    bool rtn;
206    BSOCK *sd = jcr->store_bsock;
207
208    bash_spaces(Job);
209    rtn = sd->fsend(hello_sd, Job, FD_VERSION);
210    unbash_spaces(Job);
211    Dmsg1(100, "Send to SD: %s\n", sd->msg);
212    return rtn;
213 }