~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/printing/spoolssd.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Unix SMB/Netbios implementation.
 
3
   SPOOLSS Daemon
 
4
   Copyright (C) Simo Sorce 2010
 
5
 
 
6
   This program is free software; you can redistribute it and/or modify
 
7
   it under the terms of the GNU General Public License as published by
 
8
   the Free Software Foundation; either version 3 of the License, or
 
9
   (at your option) any later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
#include "includes.h"
 
20
#include "serverid.h"
 
21
#include "smbd/smbd.h"
 
22
 
 
23
#include "messages.h"
 
24
#include "include/printing.h"
 
25
#include "printing/nt_printing_migrate_internal.h"
 
26
#include "ntdomain.h"
 
27
#include "librpc/gen_ndr/srv_winreg.h"
 
28
#include "librpc/gen_ndr/srv_spoolss.h"
 
29
#include "rpc_server/rpc_server.h"
 
30
#include "rpc_server/rpc_ep_setup.h"
 
31
#include "rpc_server/spoolss/srv_spoolss_nt.h"
 
32
 
 
33
#define SPOOLSS_PIPE_NAME "spoolss"
 
34
#define DAEMON_NAME "spoolssd"
 
35
 
 
36
void start_spoolssd(struct tevent_context *ev_ctx,
 
37
                    struct messaging_context *msg_ctx);
 
38
 
 
39
static void spoolss_reopen_logs(void)
 
40
{
 
41
        char *lfile = lp_logfile();
 
42
        int rc;
 
43
 
 
44
        if (lfile == NULL || lfile[0] == '\0') {
 
45
                rc = asprintf(&lfile, "%s/log.%s", get_dyn_LOGFILEBASE(), DAEMON_NAME);
 
46
                if (rc > 0) {
 
47
                        lp_set_logfile(lfile);
 
48
                        SAFE_FREE(lfile);
 
49
                }
 
50
        } else {
 
51
                if (strstr(lfile, DAEMON_NAME) == NULL) {
 
52
                        rc = asprintf(&lfile, "%s.%s", lp_logfile(), DAEMON_NAME);
 
53
                        if (rc > 0) {
 
54
                                lp_set_logfile(lfile);
 
55
                                SAFE_FREE(lfile);
 
56
                        }
 
57
                }
 
58
        }
 
59
 
 
60
        reopen_logs();
 
61
}
 
62
 
 
63
static void smb_conf_updated(struct messaging_context *msg,
 
64
                             void *private_data,
 
65
                             uint32_t msg_type,
 
66
                             struct server_id server_id,
 
67
                             DATA_BLOB *data)
 
68
{
 
69
        struct tevent_context *ev_ctx = talloc_get_type_abort(private_data,
 
70
                                                             struct tevent_context);
 
71
 
 
72
        DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
 
73
        change_to_root_user();
 
74
        reload_printers(ev_ctx, msg);
 
75
        spoolss_reopen_logs();
 
76
}
 
77
 
 
78
static void spoolss_sig_term_handler(struct tevent_context *ev,
 
79
                                     struct tevent_signal *se,
 
80
                                     int signum,
 
81
                                     int count,
 
82
                                     void *siginfo,
 
83
                                     void *private_data)
 
84
{
 
85
        exit_server_cleanly("termination signal");
 
86
}
 
87
 
 
88
static void spoolss_setup_sig_term_handler(struct tevent_context *ev_ctx)
 
89
{
 
90
        struct tevent_signal *se;
 
91
 
 
92
        se = tevent_add_signal(ev_ctx,
 
93
                               ev_ctx,
 
94
                               SIGTERM, 0,
 
95
                               spoolss_sig_term_handler,
 
96
                               NULL);
 
97
        if (!se) {
 
98
                exit_server("failed to setup SIGTERM handler");
 
99
        }
 
100
}
 
101
 
 
102
static void spoolss_sig_hup_handler(struct tevent_context *ev,
 
103
                                    struct tevent_signal *se,
 
104
                                    int signum,
 
105
                                    int count,
 
106
                                    void *siginfo,
 
107
                                    void *private_data)
 
108
{
 
109
        struct messaging_context *msg_ctx = talloc_get_type_abort(private_data,
 
110
                                                                  struct messaging_context);
 
111
 
 
112
        change_to_root_user();
 
113
        DEBUG(1,("Reloading printers after SIGHUP\n"));
 
114
        reload_printers(ev, msg_ctx);
 
115
        spoolss_reopen_logs();
 
116
}
 
117
 
 
118
static void spoolss_setup_sig_hup_handler(struct tevent_context *ev_ctx,
 
119
                                          struct messaging_context *msg_ctx)
 
120
{
 
121
        struct tevent_signal *se;
 
122
 
 
123
        se = tevent_add_signal(ev_ctx,
 
124
                               ev_ctx,
 
125
                               SIGHUP, 0,
 
126
                               spoolss_sig_hup_handler,
 
127
                               msg_ctx);
 
128
        if (!se) {
 
129
                exit_server("failed to setup SIGHUP handler");
 
130
        }
 
131
}
 
132
 
 
133
static bool spoolss_init_cb(void *ptr)
 
134
{
 
135
        struct messaging_context *msg_ctx = talloc_get_type_abort(
 
136
                ptr, struct messaging_context);
 
137
 
 
138
        return nt_printing_tdb_migrate(msg_ctx);
 
139
}
 
140
 
 
141
static bool spoolss_shutdown_cb(void *ptr)
 
142
{
 
143
        srv_spoolss_cleanup();
 
144
 
 
145
        return true;
 
146
}
 
147
 
 
148
void start_spoolssd(struct tevent_context *ev_ctx,
 
149
                    struct messaging_context *msg_ctx)
 
150
{
 
151
        struct rpc_srv_callbacks spoolss_cb;
 
152
        pid_t pid;
 
153
        NTSTATUS status;
 
154
        int ret;
 
155
 
 
156
        DEBUG(1, ("Forking SPOOLSS Daemon\n"));
 
157
 
 
158
        pid = sys_fork();
 
159
 
 
160
        if (pid == -1) {
 
161
                DEBUG(0, ("Failed to fork SPOOLSS [%s], aborting ...\n",
 
162
                           strerror(errno)));
 
163
                exit(1);
 
164
        }
 
165
 
 
166
        if (pid) {
 
167
                /* parent */
 
168
                return;
 
169
        }
 
170
 
 
171
        /* child */
 
172
        close_low_fds(false);
 
173
 
 
174
        status = reinit_after_fork(msg_ctx,
 
175
                                   ev_ctx,
 
176
                                   procid_self(), true);
 
177
        if (!NT_STATUS_IS_OK(status)) {
 
178
                DEBUG(0,("reinit_after_fork() failed\n"));
 
179
                smb_panic("reinit_after_fork() failed");
 
180
        }
 
181
 
 
182
        spoolss_reopen_logs();
 
183
 
 
184
        spoolss_setup_sig_term_handler(ev_ctx);
 
185
        spoolss_setup_sig_hup_handler(ev_ctx, msg_ctx);
 
186
 
 
187
        if (!serverid_register(procid_self(),
 
188
                                FLAG_MSG_GENERAL|FLAG_MSG_SMBD
 
189
                                |FLAG_MSG_PRINT_GENERAL)) {
 
190
                exit(1);
 
191
        }
 
192
 
 
193
        if (!locking_init()) {
 
194
                exit(1);
 
195
        }
 
196
 
 
197
        messaging_register(msg_ctx, NULL,
 
198
                           MSG_PRINTER_UPDATE, print_queue_receive);
 
199
        messaging_register(msg_ctx, ev_ctx,
 
200
                           MSG_SMB_CONF_UPDATED, smb_conf_updated);
 
201
 
 
202
        /*
 
203
         * Initialize spoolss with an init function to convert printers first.
 
204
         * static_init_rpc will try to initialize the spoolss server too but you
 
205
         * can't register it twice.
 
206
         */
 
207
        spoolss_cb.init = spoolss_init_cb;
 
208
        spoolss_cb.shutdown = spoolss_shutdown_cb;
 
209
        spoolss_cb.private_data = msg_ctx;
 
210
 
 
211
        status = rpc_winreg_init(NULL);
 
212
        if (!NT_STATUS_IS_OK(status)) {
 
213
                DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n",
 
214
                          nt_errstr(status)));
 
215
                exit(1);
 
216
        }
 
217
 
 
218
        status = rpc_spoolss_init(&spoolss_cb);
 
219
        if (!NT_STATUS_IS_OK(status)) {
 
220
                DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n",
 
221
                          nt_errstr(status)));
 
222
                exit(1);
 
223
        }
 
224
 
 
225
        if (!setup_named_pipe_socket(SPOOLSS_PIPE_NAME, ev_ctx)) {
 
226
                exit(1);
 
227
        }
 
228
 
 
229
        status = rpc_ep_setup_register(ev_ctx, msg_ctx, &ndr_table_spoolss, NULL, 0);
 
230
        if (!NT_STATUS_IS_OK(status)) {
 
231
                DEBUG(0, ("Failed to register spoolss endpoint! (%s)\n",
 
232
                          nt_errstr(status)));
 
233
                exit(1);
 
234
        }
 
235
 
 
236
        DEBUG(1, ("SPOOLSS Daemon Started (%d)\n", getpid()));
 
237
 
 
238
        /* loop forever */
 
239
        ret = tevent_loop_wait(ev_ctx);
 
240
 
 
241
        /* should not be reached */
 
242
        DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
 
243
                 ret, (ret == 0) ? "out of events" : strerror(errno)));
 
244
        exit(1);
 
245
}