~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/lib/sharesec.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:
18
18
 */
19
19
 
20
20
#include "includes.h"
 
21
#include "system/filesys.h"
 
22
#include "../libcli/security/security.h"
 
23
#include "../librpc/gen_ndr/ndr_security.h"
 
24
#include "dbwrap.h"
 
25
#include "util_tdb.h"
21
26
 
22
27
/*******************************************************************
23
28
 Create the share security tdb.
26
31
static struct db_context *share_db; /* used for share security descriptors */
27
32
#define SHARE_DATABASE_VERSION_V1 1
28
33
#define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
 
34
#define SHARE_DATABASE_VERSION_V3 3 /* canonicalized sharenames as lower case */
29
35
 
 
36
#define SHARE_SECURITY_DB_KEY_PREFIX_STR "SECDESC/"
30
37
/* Map generic permissions to file object specific permissions */
31
38
 
32
39
extern const struct generic_mapping file_generic_mapping;
37
44
        return 0;
38
45
}
39
46
 
 
47
/*****************************************************
 
48
 Looking for keys of the form: SHARE_SECURITY_DB_KEY_PREFIX_STR + "non lower case str".
 
49
 If we find one re-write it into a canonical case form.
 
50
*****************************************************/
 
51
 
 
52
static int upgrade_v2_to_v3(struct db_record *rec, void *priv)
 
53
{
 
54
        size_t prefix_len = strlen(SHARE_SECURITY_DB_KEY_PREFIX_STR);
 
55
        const char *servicename = NULL;
 
56
        char *c_servicename = NULL;
 
57
        char *newkey = NULL;
 
58
        bool *p_upgrade_ok = (bool *)priv;
 
59
        NTSTATUS status;
 
60
 
 
61
        /* Is there space for a one character sharename ? */
 
62
        if (rec->key.dsize <= prefix_len+2) {
 
63
                return 0;
 
64
        }
 
65
 
 
66
        /* Does it start with the share key prefix ? */
 
67
        if (memcmp(rec->key.dptr, SHARE_SECURITY_DB_KEY_PREFIX_STR,
 
68
                        prefix_len) != 0) {
 
69
                return 0;
 
70
        }
 
71
 
 
72
        /* Is it a null terminated string as a key ? */
 
73
        if (rec->key.dptr[rec->key.dsize-1] != '\0') {
 
74
                return 0;
 
75
        }
 
76
 
 
77
        /* Bytes after the prefix are the sharename string. */
 
78
        servicename = (char *)&rec->key.dptr[prefix_len];
 
79
        c_servicename = canonicalize_servicename(talloc_tos(), servicename);
 
80
        if (!c_servicename) {
 
81
                smb_panic("out of memory upgrading share security db from v2 -> v3");
 
82
        }
 
83
 
 
84
        if (strcmp(servicename, c_servicename) == 0) {
 
85
                /* Old and new names match. No canonicalization needed. */
 
86
                TALLOC_FREE(c_servicename);
 
87
                return 0;
 
88
        }
 
89
 
 
90
        /* Oops. Need to canonicalize name, delete old then store new. */
 
91
        status = rec->delete_rec(rec);
 
92
        if (!NT_STATUS_IS_OK(status)) {
 
93
                DEBUG(1, ("upgrade_v2_to_v3: Failed to delete secdesc for "
 
94
                          "%s: %s\n", rec->key.dptr, nt_errstr(status)));
 
95
                TALLOC_FREE(c_servicename);
 
96
                *p_upgrade_ok = false;
 
97
                return -1;
 
98
        } else {
 
99
                DEBUG(10, ("upgrade_v2_to_v3: deleted secdesc for "
 
100
                          "%s\n", rec->key.dptr ));
 
101
        }
 
102
 
 
103
        if (!(newkey = talloc_asprintf(talloc_tos(),
 
104
                        SHARE_SECURITY_DB_KEY_PREFIX_STR "%s",
 
105
                        c_servicename))) {
 
106
                smb_panic("out of memory upgrading share security db from v2 -> v3");
 
107
        }
 
108
 
 
109
        status = dbwrap_store(share_db,
 
110
                                string_term_tdb_data(newkey),
 
111
                                rec->value,
 
112
                                TDB_REPLACE);
 
113
 
 
114
        if (!NT_STATUS_IS_OK(status)) {
 
115
                DEBUG(1, ("upgrade_v2_to_v3: Failed to store secdesc for "
 
116
                          "%s: %s\n", c_servicename, nt_errstr(status)));
 
117
                TALLOC_FREE(c_servicename);
 
118
                TALLOC_FREE(newkey);
 
119
                *p_upgrade_ok = false;
 
120
                return -1;
 
121
        } else {
 
122
                DEBUG(10, ("upgrade_v2_to_v3: stored secdesc for "
 
123
                          "%s\n", newkey ));
 
124
        }
 
125
 
 
126
        TALLOC_FREE(newkey);
 
127
        TALLOC_FREE(c_servicename);
 
128
 
 
129
        return 0;
 
130
}
 
131
 
40
132
bool share_info_db_init(void)
41
133
{
42
134
        const char *vstring = "INFO/version";
43
135
        int32 vers_id;
 
136
        int ret;
 
137
        bool upgrade_ok = true;
44
138
 
45
139
        if (share_db != NULL) {
46
140
                return True;
55
149
        }
56
150
 
57
151
        vers_id = dbwrap_fetch_int32(share_db, vstring);
58
 
        if (vers_id == SHARE_DATABASE_VERSION_V2) {
 
152
        if (vers_id == SHARE_DATABASE_VERSION_V3) {
59
153
                return true;
60
154
        }
61
155
 
66
160
        }
67
161
 
68
162
        vers_id = dbwrap_fetch_int32(share_db, vstring);
69
 
        if (vers_id == SHARE_DATABASE_VERSION_V2) {
 
163
        if (vers_id == SHARE_DATABASE_VERSION_V3) {
70
164
                /*
71
165
                 * Race condition
72
166
                 */
76
170
                return true;
77
171
        }
78
172
 
 
173
        /* Move to at least V2. */
 
174
 
79
175
        /* Cope with byte-reversed older versions of the db. */
80
176
        if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
81
177
                /* Written on a bigendian machine with old fetch_int code. Save as le. */
89
185
        }
90
186
 
91
187
        if (vers_id != SHARE_DATABASE_VERSION_V2) {
92
 
                int ret;
93
188
                ret = share_db->traverse(share_db, delete_fn, NULL);
94
189
                if (ret < 0) {
95
190
                        DEBUG(0, ("traverse failed\n"));
102
197
                }
103
198
        }
104
199
 
 
200
        /* Finally upgrade to version 3, with canonicalized sharenames. */
 
201
 
 
202
        ret = share_db->traverse(share_db, upgrade_v2_to_v3, &upgrade_ok);
 
203
        if (ret < 0 || upgrade_ok == false) {
 
204
                DEBUG(0, ("traverse failed\n"));
 
205
                goto cancel;
 
206
        }
 
207
        if (dbwrap_store_int32(share_db, vstring,
 
208
                               SHARE_DATABASE_VERSION_V3) != 0) {
 
209
                DEBUG(0, ("dbwrap_store_int32 failed\n"));
 
210
                goto cancel;
 
211
        }
 
212
 
105
213
        if (share_db->transaction_commit(share_db) != 0) {
106
214
                DEBUG(0, ("transaction_commit failed\n"));
107
215
                return false;
122
230
 def_access is a GENERIC_XXX access mode.
123
231
 ********************************************************************/
124
232
 
125
 
SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, size_t *psize, uint32 def_access)
 
233
struct security_descriptor *get_share_security_default( TALLOC_CTX *ctx, size_t *psize, uint32 def_access)
126
234
{
127
235
        uint32_t sa;
128
 
        SEC_ACE ace;
129
 
        SEC_ACL *psa = NULL;
130
 
        SEC_DESC *psd = NULL;
 
236
        struct security_ace ace;
 
237
        struct security_acl *psa = NULL;
 
238
        struct security_descriptor *psd = NULL;
131
239
        uint32 spec_access = def_access;
132
240
 
133
241
        se_map_generic(&spec_access, &file_generic_mapping);
153
261
 Pull a security descriptor from the share tdb.
154
262
 ********************************************************************/
155
263
 
156
 
SEC_DESC *get_share_security( TALLOC_CTX *ctx, const char *servicename,
 
264
struct security_descriptor *get_share_security( TALLOC_CTX *ctx, const char *servicename,
157
265
                              size_t *psize)
158
266
{
159
267
        char *key;
160
 
        SEC_DESC *psd = NULL;
 
268
        struct security_descriptor *psd = NULL;
161
269
        TDB_DATA data;
 
270
        char *c_servicename = canonicalize_servicename(talloc_tos(), servicename);
162
271
        NTSTATUS status;
163
272
 
 
273
        if (!c_servicename) {
 
274
                return NULL;
 
275
        }
 
276
 
164
277
        if (!share_info_db_init()) {
 
278
                TALLOC_FREE(c_servicename);
165
279
                return NULL;
166
280
        }
167
281
 
168
 
        if (!(key = talloc_asprintf(ctx, "SECDESC/%s", servicename))) {
 
282
        if (!(key = talloc_asprintf(ctx, SHARE_SECURITY_DB_KEY_PREFIX_STR "%s", c_servicename))) {
 
283
                TALLOC_FREE(c_servicename);
169
284
                DEBUG(0, ("talloc_asprintf failed\n"));
170
285
                return NULL;
171
286
        }
172
287
 
 
288
        TALLOC_FREE(c_servicename);
 
289
 
173
290
        data = dbwrap_fetch_bystring(share_db, talloc_tos(), key);
174
291
 
175
292
        TALLOC_FREE(key);
186
303
        if (!NT_STATUS_IS_OK(status)) {
187
304
                DEBUG(0, ("unmarshall_sec_desc failed: %s\n",
188
305
                          nt_errstr(status)));
189
 
                return NULL;
 
306
                return get_share_security_default(ctx, psize,
 
307
                                                  GENERIC_ALL_ACCESS);
190
308
        }
191
309
 
192
 
        if (psd)
193
 
                *psize = ndr_size_security_descriptor(psd, NULL, 0);
 
310
        if (psd) {
 
311
                *psize = ndr_size_security_descriptor(psd, 0);
 
312
        } else {
 
313
                return get_share_security_default(ctx, psize,
 
314
                                                  GENERIC_ALL_ACCESS);
 
315
        }
194
316
 
195
317
        return psd;
196
318
}
199
321
 Store a security descriptor in the share db.
200
322
 ********************************************************************/
201
323
 
202
 
bool set_share_security(const char *share_name, SEC_DESC *psd)
 
324
bool set_share_security(const char *share_name, struct security_descriptor *psd)
203
325
{
204
 
        TALLOC_CTX *frame;
 
326
        TALLOC_CTX *frame = talloc_stackframe();
205
327
        char *key;
206
328
        bool ret = False;
207
329
        TDB_DATA blob;
208
330
        NTSTATUS status;
 
331
        char *c_share_name = canonicalize_servicename(frame, share_name);
 
332
 
 
333
        if (!c_share_name) {
 
334
                goto out;
 
335
        }
209
336
 
210
337
        if (!share_info_db_init()) {
211
 
                return False;
 
338
                goto out;
212
339
        }
213
340
 
214
 
        frame = talloc_stackframe();
215
 
 
216
341
        status = marshall_sec_desc(frame, psd, &blob.dptr, &blob.dsize);
217
342
 
218
343
        if (!NT_STATUS_IS_OK(status)) {
221
346
                goto out;
222
347
        }
223
348
 
224
 
        if (!(key = talloc_asprintf(frame, "SECDESC/%s", share_name))) {
 
349
        if (!(key = talloc_asprintf(frame, SHARE_SECURITY_DB_KEY_PREFIX_STR "%s", c_share_name))) {
225
350
                DEBUG(0, ("talloc_asprintf failed\n"));
226
351
                goto out;
227
352
        }
251
376
        TDB_DATA kbuf;
252
377
        char *key;
253
378
        NTSTATUS status;
 
379
        char *c_servicename = canonicalize_servicename(talloc_tos(), servicename);
 
380
 
 
381
        if (!c_servicename) {
 
382
                return NULL;
 
383
        }
254
384
 
255
385
        if (!share_info_db_init()) {
 
386
                TALLOC_FREE(c_servicename);
256
387
                return False;
257
388
        }
258
389
 
259
 
        if (!(key = talloc_asprintf(talloc_tos(), "SECDESC/%s",
260
 
                                    servicename))) {
 
390
        if (!(key = talloc_asprintf(talloc_tos(), SHARE_SECURITY_DB_KEY_PREFIX_STR "%s",
 
391
                                    c_servicename))) {
 
392
                TALLOC_FREE(c_servicename);
261
393
                return False;
262
394
        }
263
395
        kbuf = string_term_tdb_data(key);
265
397
        status = dbwrap_trans_delete(share_db, kbuf);
266
398
        if (!NT_STATUS_IS_OK(status)) {
267
399
                DEBUG(0, ("delete_share_security: Failed to delete entry for "
268
 
                          "share %s: %s\n", servicename, nt_errstr(status)));
 
400
                          "share %s: %s\n", c_servicename, nt_errstr(status)));
 
401
                TALLOC_FREE(c_servicename);
269
402
                return False;
270
403
        }
271
404
 
 
405
        TALLOC_FREE(c_servicename);
272
406
        return True;
273
407
}
274
408
 
276
410
 Can this user access with share with the required permissions ?
277
411
********************************************************************/
278
412
 
279
 
bool share_access_check(const NT_USER_TOKEN *token, const char *sharename,
280
 
                        uint32 desired_access)
 
413
bool share_access_check(const struct security_token *token,
 
414
                        const char *sharename,
 
415
                        uint32 desired_access,
 
416
                        uint32_t *pgranted)
281
417
{
282
418
        uint32 granted;
283
419
        NTSTATUS status;
284
 
        SEC_DESC *psd = NULL;
 
420
        struct security_descriptor *psd = NULL;
285
421
        size_t sd_size;
286
422
 
287
423
        psd = get_share_security(talloc_tos(), sharename, &sd_size);
294
430
 
295
431
        TALLOC_FREE(psd);
296
432
 
 
433
        if (pgranted != NULL) {
 
434
                *pgranted = granted;
 
435
        }
 
436
 
297
437
        return NT_STATUS_IS_OK(status);
298
438
}
299
439
 
301
441
 Parse the contents of an acl string from a usershare file.
302
442
***************************************************************************/
303
443
 
304
 
bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd)
 
444
bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, struct security_descriptor **ppsd)
305
445
{
306
446
        size_t s_size = 0;
307
447
        const char *pacl = acl_str;
308
448
        int num_aces = 0;
309
 
        SEC_ACE *ace_list = NULL;
310
 
        SEC_ACL *psa = NULL;
311
 
        SEC_DESC *psd = NULL;
 
449
        struct security_ace *ace_list = NULL;
 
450
        struct security_acl *psa = NULL;
 
451
        struct security_descriptor *psd = NULL;
312
452
        size_t sd_size = 0;
313
453
        int i;
314
454
 
316
456
 
317
457
        /* If the acl string is blank return "Everyone:R" */
318
458
        if (!*acl_str) {
319
 
                SEC_DESC *default_psd = get_share_security_default(ctx, &s_size, GENERIC_READ_ACCESS);
 
459
                struct security_descriptor *default_psd = get_share_security_default(ctx, &s_size, GENERIC_READ_ACCESS);
320
460
                if (!default_psd) {
321
461
                        return False;
322
462
                }
329
469
        /* Add the number of ',' characters to get the number of aces. */
330
470
        num_aces += count_chars(pacl,',');
331
471
 
332
 
        ace_list = TALLOC_ARRAY(ctx, SEC_ACE, num_aces);
 
472
        ace_list = TALLOC_ARRAY(ctx, struct security_ace, num_aces);
333
473
        if (!ace_list) {
334
474
                return False;
335
475
        }
338
478
                uint32_t sa;
339
479
                uint32 g_access;
340
480
                uint32 s_access;
341
 
                DOM_SID sid;
 
481
                struct dom_sid sid;
342
482
                char *sidstr;
343
483
                enum security_ace_type type = SEC_ACE_TYPE_ACCESS_ALLOWED;
344
484