~ubuntu-branches/ubuntu/maverick/samba/maverick-security

« back to all changes in this revision

Viewing changes to source/lib/avahi.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Mitchell
  • Date: 2009-05-18 13:26:04 UTC
  • mfrom: (0.28.5 sid)
  • Revision ID: james.westby@ubuntu.com-20090518132604-ebyuqimgymtr3h0k
Tags: 2:3.3.4-2ubuntu1
* Merge from debian unstable, remaining changes:
  + debian/patches/VERSION.patch:
    - setup SAMBA_VERSION_SUFFIX to Ubuntu.
  + 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/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted (LP: #312449)
  + debian/mksambapasswd.awk:
    - Do not add user with UID less than 1000 to smbpasswd.
  + debian/control:
    - Make libwbclient0 replace/conflict with hardy's likewise-open.
    - Don't build against ctdb.
    - Add suggests keyutils for smbfs. (LP: #300221)
  + debian/rules:
    - enable "native" PIE hardening.
    - remove --with-ctdb and --with-cluster-support=yes
  + Add ufw integration:
    - Created debian/samba.ufw profile.
    - debian/rules, debian/samba.dirs, debian/samba.files: install 
      profile
    - debian/control: have samba sugguest ufw.
* Dropped patches:
  + debian/patches/fix-upstream-bug-6186.patch: Merged upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Unix SMB/CIFS implementation.
 
3
   Connect avahi to lib/tevents
 
4
   Copyright (C) Volker Lendecke 2009
 
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
 
 
20
#include "includes.h"
 
21
 
 
22
#include <avahi-common/watch.h>
 
23
 
 
24
struct avahi_poll_context {
 
25
        struct event_context *ev;
 
26
        AvahiWatch **watches;
 
27
        AvahiTimeout **timeouts;
 
28
};
 
29
 
 
30
struct AvahiWatch {
 
31
        struct avahi_poll_context *ctx;
 
32
        struct fd_event *fde;
 
33
        int fd;
 
34
        AvahiWatchEvent latest_event;
 
35
        AvahiWatchCallback callback;
 
36
        void *userdata;
 
37
};
 
38
 
 
39
struct AvahiTimeout {
 
40
        struct avahi_poll_context *ctx;
 
41
        struct timed_event *te;
 
42
        AvahiTimeoutCallback callback;
 
43
        void *userdata;
 
44
};
 
45
 
 
46
static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event)
 
47
{
 
48
        return ((event & AVAHI_WATCH_IN) ? EVENT_FD_READ : 0)
 
49
                | ((event & AVAHI_WATCH_OUT) ? EVENT_FD_WRITE : 0);
 
50
}
 
51
 
 
52
static void avahi_fd_handler(struct event_context *ev,
 
53
                             struct fd_event *fde, uint16_t flags,
 
54
                             void *private_data);
 
55
 
 
56
static AvahiWatch *avahi_watch_new(const AvahiPoll *api, int fd,
 
57
                                   AvahiWatchEvent event,
 
58
                                   AvahiWatchCallback callback,
 
59
                                   void *userdata)
 
60
{
 
61
        struct avahi_poll_context *ctx = talloc_get_type_abort(
 
62
                api->userdata, struct avahi_poll_context);
 
63
        int num_watches = talloc_get_size(ctx->watches)/sizeof(*ctx->watches);
 
64
        AvahiWatch **tmp, *watch_ctx;
 
65
 
 
66
        tmp = talloc_realloc(ctx, ctx->watches, AvahiWatch *, num_watches + 1);
 
67
        if (tmp == NULL) {
 
68
                return NULL;
 
69
        }
 
70
        ctx->watches = tmp;
 
71
 
 
72
        watch_ctx = talloc(tmp, AvahiWatch);
 
73
        if (watch_ctx == NULL) {
 
74
                goto fail;
 
75
        }
 
76
        ctx->watches[num_watches] = watch_ctx;
 
77
 
 
78
        watch_ctx->ctx = ctx;
 
79
        watch_ctx->fde = event_add_fd(ctx->ev, watch_ctx, fd,
 
80
                                      avahi_flags_map_to_tevent(event),
 
81
                                      avahi_fd_handler, watch_ctx);
 
82
        if (watch_ctx->fde == NULL) {
 
83
                goto fail;
 
84
        }
 
85
        watch_ctx->callback = callback;
 
86
        watch_ctx->userdata = userdata;
 
87
        return watch_ctx;
 
88
 
 
89
 fail:
 
90
        TALLOC_FREE(watch_ctx);
 
91
        ctx->watches = talloc_realloc(ctx, ctx->watches, AvahiWatch *,
 
92
                                      num_watches);
 
93
        return NULL;
 
94
}
 
95
 
 
96
static void avahi_fd_handler(struct event_context *ev,
 
97
                             struct fd_event *fde, uint16_t flags,
 
98
                             void *private_data)
 
99
{
 
100
        AvahiWatch *watch_ctx = talloc_get_type_abort(private_data, AvahiWatch);
 
101
 
 
102
        watch_ctx->latest_event =
 
103
                ((flags & EVENT_FD_READ) ? AVAHI_WATCH_IN : 0)
 
104
                | ((flags & EVENT_FD_WRITE) ? AVAHI_WATCH_OUT : 0);
 
105
 
 
106
        watch_ctx->callback(watch_ctx, watch_ctx->fd, watch_ctx->latest_event,
 
107
                            watch_ctx->userdata);
 
108
}
 
109
 
 
110
static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event)
 
111
{
 
112
        if (event & AVAHI_WATCH_IN) {
 
113
                event_fd_set_readable(w->fde);
 
114
        } else {
 
115
                event_fd_set_not_readable(w->fde);
 
116
        }
 
117
        if (event & AVAHI_WATCH_OUT) {
 
118
                event_fd_set_writeable(w->fde);
 
119
        } else {
 
120
                event_fd_set_not_writeable(w->fde);
 
121
        }
 
122
}
 
123
 
 
124
static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w)
 
125
{
 
126
        return w->latest_event;
 
127
}
 
128
 
 
129
static void avahi_watch_free(AvahiWatch *w)
 
130
{
 
131
        int i, num_watches;
 
132
        AvahiWatch **watches = w->ctx->watches;
 
133
        struct avahi_poll_context *ctx;
 
134
 
 
135
        num_watches = talloc_get_size(watches) / sizeof(*watches);
 
136
 
 
137
        for (i=0; i<num_watches; i++) {
 
138
                if (w == watches[i]) {
 
139
                        break;
 
140
                }
 
141
        }
 
142
        if (i == num_watches) {
 
143
                return;
 
144
        }
 
145
        ctx = w->ctx;
 
146
        TALLOC_FREE(w);
 
147
        memmove(&watches[i], &watches[i+1],
 
148
                sizeof(*watches) * (num_watches - i - 1));
 
149
        ctx->watches = talloc_realloc(ctx, watches, AvahiWatch *,
 
150
                                      num_watches - 1);
 
151
}
 
152
 
 
153
static void avahi_timeout_handler(struct event_context *ev,
 
154
                                  struct timed_event *te,
 
155
                                  struct timeval current_time,
 
156
                                  void *private_data);
 
157
 
 
158
static AvahiTimeout *avahi_timeout_new(const AvahiPoll *api,
 
159
                                       const struct timeval *tv,
 
160
                                       AvahiTimeoutCallback callback,
 
161
                                       void *userdata)
 
162
{
 
163
        struct avahi_poll_context *ctx = talloc_get_type_abort(
 
164
                api->userdata, struct avahi_poll_context);
 
165
        int num_timeouts = talloc_get_size(ctx->timeouts)/sizeof(*ctx->timeouts);
 
166
        AvahiTimeout **tmp, *timeout_ctx;
 
167
 
 
168
        tmp = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *,
 
169
                             num_timeouts + 1);
 
170
        if (tmp == NULL) {
 
171
                return NULL;
 
172
        }
 
173
        ctx->timeouts = tmp;
 
174
 
 
175
        timeout_ctx = talloc(tmp, AvahiTimeout);
 
176
        if (timeout_ctx == NULL) {
 
177
                goto fail;
 
178
        }
 
179
        ctx->timeouts[num_timeouts] = timeout_ctx;
 
180
 
 
181
        timeout_ctx->ctx = ctx;
 
182
        if (tv == NULL) {
 
183
                timeout_ctx->te = NULL;
 
184
        } else {
 
185
                timeout_ctx->te = event_add_timed(ctx->ev, timeout_ctx,
 
186
                                                  *tv, avahi_timeout_handler,
 
187
                                                  timeout_ctx);
 
188
                if (timeout_ctx->te == NULL) {
 
189
                        goto fail;
 
190
                }
 
191
        }
 
192
        timeout_ctx->callback = callback;
 
193
        timeout_ctx->userdata = userdata;
 
194
        return timeout_ctx;
 
195
 
 
196
 fail:
 
197
        TALLOC_FREE(timeout_ctx);
 
198
        ctx->timeouts = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *,
 
199
                                       num_timeouts);
 
200
        return NULL;
 
201
}
 
202
 
 
203
static void avahi_timeout_handler(struct event_context *ev,
 
204
                                  struct timed_event *te,
 
205
                                  struct timeval current_time,
 
206
                                  void *private_data)
 
207
{
 
208
        AvahiTimeout *timeout_ctx = talloc_get_type_abort(
 
209
                private_data, AvahiTimeout);
 
210
 
 
211
        TALLOC_FREE(timeout_ctx->te);
 
212
        timeout_ctx->callback(timeout_ctx, timeout_ctx->userdata);
 
213
}
 
214
 
 
215
static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv)
 
216
{
 
217
        TALLOC_FREE(t->te);
 
218
 
 
219
        if (tv == NULL) {
 
220
                /*
 
221
                 * Disable this timer
 
222
                 */
 
223
                return;
 
224
        }
 
225
 
 
226
        t->te = event_add_timed(t->ctx->ev, t, *tv, avahi_timeout_handler, t);
 
227
        /*
 
228
         * No failure mode defined here
 
229
         */
 
230
        SMB_ASSERT(t->te != NULL);
 
231
}
 
232
 
 
233
static void avahi_timeout_free(AvahiTimeout *t)
 
234
{
 
235
        int i, num_timeouts;
 
236
        AvahiTimeout **timeouts = t->ctx->timeouts;
 
237
        struct avahi_poll_context *ctx;
 
238
 
 
239
        num_timeouts = talloc_get_size(timeouts)/sizeof(*timeouts);
 
240
 
 
241
        for (i=0; i<num_timeouts; i++) {
 
242
                if (t == timeouts[i]) {
 
243
                        break;
 
244
                }
 
245
        }
 
246
        if (i == num_timeouts) {
 
247
                return;
 
248
        }
 
249
        ctx = t->ctx;
 
250
        TALLOC_FREE(t);
 
251
        memmove(&timeouts[i], &timeouts[i+1],
 
252
                sizeof(*timeouts) * (num_timeouts - i - 1));
 
253
        ctx->timeouts = talloc_realloc(ctx, timeouts, AvahiTimeout *,
 
254
                                       num_timeouts - 1);
 
255
}
 
256
 
 
257
struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx,
 
258
                                    struct event_context *ev)
 
259
{
 
260
        struct AvahiPoll *result;
 
261
        struct avahi_poll_context *ctx;
 
262
 
 
263
        result = talloc(mem_ctx, struct AvahiPoll);
 
264
        if (result == NULL) {
 
265
                return result;
 
266
        }
 
267
        ctx = talloc_zero(result, struct avahi_poll_context);
 
268
        if (ctx == NULL) {
 
269
                TALLOC_FREE(result);
 
270
                return NULL;
 
271
        }
 
272
        ctx->ev = ev;
 
273
 
 
274
        result->watch_new               = avahi_watch_new;
 
275
        result->watch_update            = avahi_watch_update;
 
276
        result->watch_get_events        = avahi_watch_get_events;
 
277
        result->watch_free              = avahi_watch_free;
 
278
        result->timeout_new             = avahi_timeout_new;
 
279
        result->timeout_update          = avahi_timeout_update;
 
280
        result->timeout_free            = avahi_timeout_free;
 
281
        result->userdata                = ctx;
 
282
 
 
283
        return result;
 
284
}