Coverage Report

Created: 2026-01-16 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/smbd/server_reload.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   Main SMB server routines
4
   Copyright (C) Andrew Tridgell    1992-1998
5
   Copyright (C) Martin Pool      2002
6
   Copyright (C) Jelmer Vernooij    2002-2003
7
   Copyright (C) Volker Lendecke    1993-2007
8
   Copyright (C) Jeremy Allison     1993-2007
9
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
*/
23
24
#include "includes.h"
25
#include "smbd/smbd.h"
26
#include "smbd/globals.h"
27
#include "nt_printing.h"
28
#include "printing/pcap.h"
29
#include "printing/printer_list.h"
30
#include "printing/load.h"
31
#include "auth.h"
32
#include "messages.h"
33
#include "lib/param/loadparm.h"
34
35
/*
36
 * The persistent pcap cache is populated by the background print process. Per
37
 * client smbds should only reload their printer share inventories if this
38
 * information has changed. Use reload_last_pcap_time to detect this.
39
 */
40
static time_t reload_last_pcap_time = 0;
41
42
bool snum_is_shared_printer(int snum)
43
0
{
44
0
  return (lp_browseable(snum) && lp_snum_ok(snum) && lp_printable(snum));
45
0
}
46
47
/**
48
 * @brief Purge stale printer shares and reload from pre-populated pcap cache.
49
 *
50
 * This function should normally only be called as a callback on a successful
51
 * pcap_cache_reload(), or on client enumeration.
52
 */
53
void delete_and_reload_printers(void)
54
0
{
55
0
  int n_services;
56
0
  int pnum;
57
0
  int snum;
58
0
  const char *pname;
59
0
  bool ok;
60
0
  time_t pcap_last_update;
61
0
  TALLOC_CTX *frame = NULL;
62
0
  const struct loadparm_substitution *lp_sub =
63
0
    loadparm_s3_global_substitution();
64
65
0
  if (!lp_load_printers()) {
66
0
    DBG_DEBUG("skipping printer reload: disabled\n");
67
0
    return;
68
0
  }
69
70
0
  frame = talloc_stackframe();
71
0
  ok = pcap_cache_loaded(&pcap_last_update);
72
0
  if (!ok) {
73
0
    DEBUG(1, ("pcap cache not loaded\n"));
74
0
    talloc_free(frame);
75
0
    return;
76
0
  }
77
78
0
  if (reload_last_pcap_time == pcap_last_update) {
79
0
    DEBUG(5, ("skipping printer reload, already up to date.\n"));
80
0
    talloc_free(frame);
81
0
    return;
82
0
  }
83
0
  reload_last_pcap_time = pcap_last_update;
84
85
  /* Get pcap printers updated */
86
0
  load_printers();
87
88
0
  n_services = lp_numservices();
89
0
  pnum = lp_servicenumber(PRINTERS_NAME);
90
91
0
  DEBUG(10, ("reloading printer services from pcap cache\n"));
92
93
  /*
94
   * Add default config for printers added to smb.conf file and remove
95
   * stale printers
96
   */
97
0
  for (snum = 0; snum < n_services; snum++) {
98
    /* avoid removing PRINTERS_NAME */
99
0
    if (snum == pnum) {
100
0
      continue;
101
0
    }
102
103
    /* skip no-printer services */
104
0
    if (!snum_is_shared_printer(snum)) {
105
0
      continue;
106
0
    }
107
108
0
    pname = lp_printername(frame, lp_sub, snum);
109
110
    /* check printer, but avoid removing non-autoloaded printers */
111
0
    if (lp_autoloaded(snum) &&
112
0
        !printer_list_printername_exists(pname)) {
113
0
      lp_killservice(snum);
114
0
    }
115
0
  }
116
117
  /* Make sure deleted printers are gone */
118
0
  load_printers();
119
120
0
  talloc_free(frame);
121
0
}
122
123
/****************************************************************************
124
 Reload the services file.
125
**************************************************************************/
126
127
bool reload_services(struct smbd_server_connection *sconn,
128
         bool (*snumused) (struct smbd_server_connection *, int),
129
         bool test)
130
0
{
131
0
  const struct loadparm_substitution *lp_sub =
132
0
    loadparm_s3_global_substitution();
133
0
  struct smbXsrv_connection *xconn = NULL;
134
0
  bool ret;
135
136
0
  if (lp_loaded()) {
137
0
    char *fname = lp_next_configfile(talloc_tos(), lp_sub);
138
0
    if (file_exist(fname) &&
139
0
        !strcsequal(fname, get_dyn_CONFIGFILE())) {
140
0
      set_dyn_CONFIGFILE(fname);
141
0
      test = False;
142
0
    }
143
0
    TALLOC_FREE(fname);
144
0
  }
145
146
0
  reopen_logs();
147
148
0
  if (test && !lp_file_list_changed())
149
0
    return(True);
150
151
0
  lp_killunused(sconn, snumused);
152
153
0
  ret = lp_load_with_shares(get_dyn_CONFIGFILE());
154
155
  /* perhaps the config filename is now set */
156
0
  if (!test) {
157
0
    reload_services(sconn, snumused, true);
158
0
  }
159
160
0
  reopen_logs();
161
162
0
  load_interfaces();
163
164
0
  if (sconn != NULL && sconn->client != NULL) {
165
0
    xconn = sconn->client->connections;
166
0
  }
167
0
  for (;xconn != NULL; xconn = xconn->next) {
168
0
    set_socket_options(xconn->transport.sock, "SO_KEEPALIVE");
169
0
    set_socket_options(xconn->transport.sock, lp_socket_options());
170
0
  }
171
172
0
  mangle_reset_cache();
173
0
  flush_dfree_cache();
174
175
0
  return(ret);
176
0
}