~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/lib/privileges.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:
22
22
 
23
23
 
24
24
#include "includes.h"
 
25
#include "lib/privileges.h"
 
26
#include "dbwrap.h"
 
27
#include "libcli/security/privileges_private.h"
 
28
#include "../libcli/security/security.h"
 
29
#include "passdb.h"
25
30
 
26
31
#define PRIVPREFIX              "PRIV_"
27
32
 
28
33
typedef struct {
29
 
        size_t count;
30
 
        DOM_SID *list;
 
34
        uint32_t count;
 
35
        struct dom_sid *list;
31
36
} SID_LIST;
32
37
 
33
38
typedef struct {
34
39
        TALLOC_CTX *mem_ctx;
35
 
        SE_PRIV privilege;
 
40
        uint64_t privilege;
36
41
        SID_LIST sids;
37
42
} PRIV_SID_LIST;
38
43
 
39
 
 
40
 
static bool get_privileges( const DOM_SID *sid, SE_PRIV *mask )
 
44
/*
 
45
  interpret an old style SE_PRIV structure
 
46
 */
 
47
static uint64_t map_old_SE_PRIV(unsigned char *dptr)
 
48
{
 
49
        uint32_t *old_masks = (uint32_t *)dptr;
 
50
        /*
 
51
         * the old privileges code only ever used up to 0x800, except
 
52
         * for a special case of 'SE_ALL_PRIVS' which was 0xFFFFFFFF
 
53
         */
 
54
        if (old_masks[0] == 0xFFFFFFFF) {
 
55
                /* they set all privileges */
 
56
                return SE_ALL_PRIVS;
 
57
        }
 
58
 
 
59
        /* the old code used the machine byte order, but we don't know
 
60
         * the byte order of the machine that wrote it. However we can
 
61
         * tell what byte order it was by taking advantage of the fact
 
62
         * that it only ever use up to 0x800
 
63
         */
 
64
        if (dptr[0] || dptr[1]) {
 
65
                /* it was little endian */
 
66
                return IVAL(dptr, 0);
 
67
        }
 
68
 
 
69
        /* it was either zero or big-endian */
 
70
        return RIVAL(dptr, 0);
 
71
}
 
72
 
 
73
 
 
74
static bool get_privileges( const struct dom_sid *sid, uint64_t *mask )
41
75
{
42
76
        struct db_context *db = get_account_pol_db();
43
77
        fstring tmp, keystr;
59
93
        data = dbwrap_fetch_bystring( db, talloc_tos(), keystr );
60
94
 
61
95
        if ( !data.dptr ) {
62
 
                DEBUG(3, ("get_privileges: No privileges assigned to SID "
 
96
                DEBUG(4, ("get_privileges: No privileges assigned to SID "
63
97
                          "[%s]\n", sid_string_dbg(sid)));
64
98
                return False;
65
99
        }
66
100
 
67
 
        SMB_ASSERT( data.dsize == sizeof( SE_PRIV ) );
68
 
 
69
 
        se_priv_copy( mask, (SE_PRIV*)data.dptr );
 
101
        if (data.dsize == 4*4) {
 
102
                /* it's an old style SE_PRIV structure. */
 
103
                *mask = map_old_SE_PRIV(data.dptr);
 
104
        } else {
 
105
                if (data.dsize != sizeof( uint64_t ) ) {
 
106
                        DEBUG(3, ("get_privileges: Invalid privileges record assigned to SID "
 
107
                                  "[%s]\n", sid_string_dbg(sid)));
 
108
                        return False;
 
109
                }
 
110
 
 
111
                *mask = BVAL(data.dptr, 0);
 
112
        }
 
113
 
70
114
        TALLOC_FREE(data.dptr);
71
115
 
72
116
        return True;
76
120
 Store the privilege mask (set) for a given SID
77
121
****************************************************************************/
78
122
 
79
 
static bool set_privileges( const DOM_SID *sid, SE_PRIV *mask )
 
123
static bool set_privileges( const struct dom_sid *sid, uint64_t mask )
80
124
{
81
125
        struct db_context *db = get_account_pol_db();
 
126
        uint8_t privbuf[8];
82
127
        fstring tmp, keystr;
83
128
        TDB_DATA data;
84
129
 
97
142
 
98
143
        fstr_sprintf(keystr, "%s%s", PRIVPREFIX, sid_to_fstring(tmp, sid));
99
144
 
100
 
        /* no packing.  static size structure, just write it out */
 
145
        /* This writes the 64 bit bitmask out in little endian format */
 
146
        SBVAL(privbuf,0,mask);
101
147
 
102
 
        data.dptr  = (uint8 *)mask;
103
 
        data.dsize = sizeof(SE_PRIV);
 
148
        data.dptr  = privbuf;
 
149
        data.dsize = sizeof(privbuf);
104
150
 
105
151
        return NT_STATUS_IS_OK(dbwrap_store_bystring(db, keystr, data,
106
152
                                                     TDB_REPLACE));
110
156
 get a list of all privileges for all sids in the list
111
157
*********************************************************************/
112
158
 
113
 
bool get_privileges_for_sids(SE_PRIV *privileges, DOM_SID *slist, int scount)
 
159
bool get_privileges_for_sids(uint64_t *privileges, struct dom_sid *slist, int scount)
114
160
{
115
 
        SE_PRIV mask;
 
161
        uint64_t mask;
116
162
        int i;
117
163
        bool found = False;
118
164
 
119
 
        se_priv_copy( privileges, &se_priv_none );
 
165
        *privileges = 0;
120
166
 
121
167
        for ( i=0; i<scount; i++ ) {
122
168
                /* don't add unless we actually have a privilege assigned */
125
171
                        continue;
126
172
 
127
173
                DEBUG(5,("get_privileges_for_sids: sid = %s\nPrivilege "
128
 
                         "set:\n", sid_string_dbg(&slist[i])));
129
 
                dump_se_priv( DBGC_ALL, 5, &mask );
 
174
                         "set: 0x%llx\n", sid_string_dbg(&slist[i]),
 
175
                         (unsigned long long)mask));
130
176
 
131
 
                se_priv_add( privileges, &mask );
 
177
                *privileges |= mask;
132
178
                found = True;
133
179
        }
134
180
 
135
181
        return found;
136
182
}
137
183
 
 
184
NTSTATUS get_privileges_for_sid_as_set(TALLOC_CTX *mem_ctx, PRIVILEGE_SET **privileges, struct dom_sid *sid)
 
185
{
 
186
        uint64_t mask;
 
187
        if (!get_privileges(sid, &mask)) {
 
188
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 
189
        }
 
190
 
 
191
        *privileges = talloc_zero(mem_ctx, PRIVILEGE_SET);
 
192
        if (!*privileges) {
 
193
                return NT_STATUS_NO_MEMORY;
 
194
        }
 
195
 
 
196
        if (!se_priv_to_privilege_set(*privileges, mask)) {
 
197
                return NT_STATUS_NO_MEMORY;
 
198
        }
 
199
        return NT_STATUS_OK;
 
200
}
138
201
 
139
202
/*********************************************************************
140
203
 traversal functions for privilege_enumerate_accounts
144
207
{
145
208
        PRIV_SID_LIST *priv = (PRIV_SID_LIST *)state;
146
209
        int  prefixlen = strlen(PRIVPREFIX);
147
 
        DOM_SID sid;
 
210
        struct dom_sid sid;
148
211
        fstring sid_string;
149
212
 
150
 
        /* easy check first */
151
 
 
152
 
        if (rec->value.dsize != sizeof(SE_PRIV) )
153
 
                return 0;
154
 
 
155
213
        /* check we have a PRIV_+SID entry */
156
214
 
157
215
        if ( strncmp((char *)rec->key.dptr, PRIVPREFIX, prefixlen) != 0)
159
217
 
160
218
        /* check to see if we are looking for a particular privilege */
161
219
 
162
 
        if ( !se_priv_equal(&priv->privilege, &se_priv_none) ) {
163
 
                SE_PRIV mask;
164
 
 
165
 
                se_priv_copy( &mask, (SE_PRIV*)rec->value.dptr );
 
220
        fstrcpy( sid_string, (char *)&(rec->key.dptr[strlen(PRIVPREFIX)]) );
 
221
 
 
222
        if (priv->privilege != 0) {
 
223
                uint64_t mask;
 
224
 
 
225
                if (rec->value.dsize == 4*4) {
 
226
                        mask = map_old_SE_PRIV(rec->value.dptr);
 
227
                } else {
 
228
                        if (rec->value.dsize != sizeof( uint64_t ) ) {
 
229
                                DEBUG(3, ("get_privileges: Invalid privileges record assigned to SID "
 
230
                                          "[%s]\n", sid_string));
 
231
                                return 0;
 
232
                        }
 
233
                        mask = BVAL(rec->value.dptr, 0);
 
234
                }
166
235
 
167
236
                /* if the SID does not have the specified privilege
168
237
                   then just return */
169
238
 
170
 
                if ( !is_privilege_assigned( &mask, &priv->privilege) )
 
239
                if ((mask & priv->privilege) == 0) {
171
240
                        return 0;
 
241
                }
172
242
        }
173
243
 
174
 
        fstrcpy( sid_string, (char *)&(rec->key.dptr[strlen(PRIVPREFIX)]) );
175
 
 
176
244
        /* this is a last ditch safety check to preventing returning
177
245
           and invalid SID (i've somehow run into this on development branches) */
178
246
 
199
267
 Retreive list of privileged SIDs (for _lsa_enumerate_accounts()
200
268
*********************************************************************/
201
269
 
202
 
NTSTATUS privilege_enumerate_accounts(DOM_SID **sids, int *num_sids)
 
270
NTSTATUS privilege_enumerate_accounts(struct dom_sid **sids, int *num_sids)
203
271
{
204
272
        struct db_context *db = get_account_pol_db();
205
273
        PRIV_SID_LIST priv;
210
278
 
211
279
        ZERO_STRUCT(priv);
212
280
 
213
 
        se_priv_copy( &priv.privilege, &se_priv_none );
214
 
 
215
281
        db->traverse_read(db, priv_traverse_fn, &priv);
216
282
 
217
283
        /* give the memory away; caller will free */
226
292
 Retrieve list of SIDs granted a particular privilege
227
293
*********************************************************************/
228
294
 
229
 
NTSTATUS privilege_enum_sids(const SE_PRIV *mask, TALLOC_CTX *mem_ctx,
230
 
                             DOM_SID **sids, int *num_sids)
 
295
NTSTATUS privilege_enum_sids(enum sec_privilege privilege, TALLOC_CTX *mem_ctx,
 
296
                             struct dom_sid **sids, int *num_sids)
231
297
{
232
298
        struct db_context *db = get_account_pol_db();
233
299
        PRIV_SID_LIST priv;
238
304
 
239
305
        ZERO_STRUCT(priv);
240
306
 
241
 
        se_priv_copy(&priv.privilege, mask);
 
307
        priv.privilege = sec_privilege_mask(privilege);
242
308
        priv.mem_ctx = mem_ctx;
243
309
 
244
310
        db->traverse_read(db, priv_traverse_fn, &priv);
255
321
 Add privilege to sid
256
322
****************************************************************************/
257
323
 
258
 
bool grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
 
324
static bool grant_privilege_bitmap(const struct dom_sid *sid, const uint64_t priv_mask)
259
325
{
260
 
        SE_PRIV old_mask, new_mask;
 
326
        uint64_t old_mask, new_mask;
261
327
 
262
328
        ZERO_STRUCT( old_mask );
263
329
        ZERO_STRUCT( new_mask );
264
330
 
265
331
        if ( get_privileges( sid, &old_mask ) )
266
 
                se_priv_copy( &new_mask, &old_mask );
 
332
                new_mask = old_mask;
267
333
        else
268
 
                se_priv_copy( &new_mask, &se_priv_none );
 
334
                new_mask = 0;
269
335
 
270
 
        se_priv_add( &new_mask, priv_mask );
 
336
        new_mask |= priv_mask;
271
337
 
272
338
        DEBUG(10,("grant_privilege: %s\n", sid_string_dbg(sid)));
273
339
 
274
 
        DEBUGADD( 10, ("original privilege mask:\n"));
275
 
        dump_se_priv( DBGC_ALL, 10, &old_mask );
276
 
 
277
 
        DEBUGADD( 10, ("new privilege mask:\n"));
278
 
        dump_se_priv( DBGC_ALL, 10, &new_mask );
279
 
 
280
 
        return set_privileges( sid, &new_mask );
 
340
        DEBUGADD( 10, ("original privilege mask: 0x%llx\n", (unsigned long long)new_mask));
 
341
 
 
342
        DEBUGADD( 10, ("new privilege mask:      0x%llx\n", (unsigned long long)new_mask));
 
343
 
 
344
        return set_privileges( sid, new_mask );
281
345
}
282
346
 
283
347
/*********************************************************************
284
348
 Add a privilege based on its name
285
349
*********************************************************************/
286
350
 
287
 
bool grant_privilege_by_name(DOM_SID *sid, const char *name)
 
351
bool grant_privilege_by_name(const struct dom_sid *sid, const char *name)
288
352
{
289
 
        SE_PRIV mask;
 
353
        uint64_t mask;
290
354
 
291
355
        if (! se_priv_from_name(name, &mask)) {
292
356
                DEBUG(3, ("grant_privilege_by_name: "
294
358
                return False;
295
359
        }
296
360
 
297
 
        return grant_privilege( sid, &mask );
 
361
        return grant_privilege_bitmap( sid, mask );
 
362
}
 
363
 
 
364
/***************************************************************************
 
365
 Grant a privilege set (list of LUID values) from a sid
 
366
****************************************************************************/
 
367
 
 
368
bool grant_privilege_set(const struct dom_sid *sid, struct lsa_PrivilegeSet *set)
 
369
{
 
370
        uint64_t privilege_mask;
 
371
        if (!privilege_set_to_se_priv(&privilege_mask, set)) {
 
372
                return false;
 
373
        }
 
374
        return grant_privilege_bitmap(sid, privilege_mask);
298
375
}
299
376
 
300
377
/***************************************************************************
301
378
 Remove privilege from sid
302
379
****************************************************************************/
303
380
 
304
 
bool revoke_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask)
 
381
static bool revoke_privilege_bitmap(const struct dom_sid *sid, const uint64_t priv_mask)
305
382
{
306
 
        SE_PRIV mask;
 
383
        uint64_t mask;
307
384
 
308
385
        /* if the user has no privileges, then we can't revoke any */
309
386
 
312
389
 
313
390
        DEBUG(10,("revoke_privilege: %s\n", sid_string_dbg(sid)));
314
391
 
315
 
        DEBUGADD( 10, ("original privilege mask:\n"));
316
 
        dump_se_priv( DBGC_ALL, 10, &mask );
317
 
 
318
 
        se_priv_remove( &mask, priv_mask );
319
 
 
320
 
        DEBUGADD( 10, ("new privilege mask:\n"));
321
 
        dump_se_priv( DBGC_ALL, 10, &mask );
322
 
 
323
 
        return set_privileges( sid, &mask );
 
392
        DEBUGADD( 10, ("original privilege mask: 0x%llx\n", (unsigned long long)mask));
 
393
 
 
394
        mask &= ~priv_mask;
 
395
 
 
396
        DEBUGADD( 10, ("new privilege mask:      0x%llx\n", (unsigned long long)mask));
 
397
 
 
398
        return set_privileges( sid, mask );
 
399
}
 
400
 
 
401
/***************************************************************************
 
402
 Remove a privilege set (list of LUID values) from a sid
 
403
****************************************************************************/
 
404
 
 
405
bool revoke_privilege_set(const struct dom_sid *sid, struct lsa_PrivilegeSet *set)
 
406
{
 
407
        uint64_t privilege_mask;
 
408
        if (!privilege_set_to_se_priv(&privilege_mask, set)) {
 
409
                return false;
 
410
        }
 
411
        return revoke_privilege_bitmap(sid, privilege_mask);
324
412
}
325
413
 
326
414
/*********************************************************************
327
415
 Revoke all privileges
328
416
*********************************************************************/
329
417
 
330
 
bool revoke_all_privileges( DOM_SID *sid )
 
418
bool revoke_all_privileges( const struct dom_sid *sid )
331
419
{
332
 
        return revoke_privilege( sid, &se_priv_all );
 
420
        return revoke_privilege_bitmap( sid, SE_ALL_PRIVS);
333
421
}
334
422
 
335
423
/*********************************************************************
336
424
 Add a privilege based on its name
337
425
*********************************************************************/
338
426
 
339
 
bool revoke_privilege_by_name(DOM_SID *sid, const char *name)
 
427
bool revoke_privilege_by_name(const struct dom_sid *sid, const char *name)
340
428
{
341
 
        SE_PRIV mask;
 
429
        uint64_t mask;
342
430
 
343
431
        if (! se_priv_from_name(name, &mask)) {
344
432
                DEBUG(3, ("revoke_privilege_by_name: "
346
434
                return False;
347
435
        }
348
436
 
349
 
        return revoke_privilege(sid, &mask);
 
437
        return revoke_privilege_bitmap(sid, mask);
350
438
 
351
439
}
352
440
 
354
442
 Retrieve the SIDs assigned to a given privilege
355
443
****************************************************************************/
356
444
 
357
 
NTSTATUS privilege_create_account(const DOM_SID *sid )
 
445
NTSTATUS privilege_create_account(const struct dom_sid *sid )
358
446
{
359
 
        return ( grant_privilege(sid, &se_priv_none) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL);
 
447
        return ( grant_privilege_bitmap(sid, 0) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL);
360
448
}
361
449
 
362
450
/***************************************************************************
387
475
        return dbwrap_delete_bystring(db, keystr);
388
476
}
389
477
 
390
 
/****************************************************************************
391
 
 initialise a privilege list and set the talloc context
392
 
 ****************************************************************************/
393
 
 
394
 
NTSTATUS privilege_set_init(PRIVILEGE_SET *priv_set)
395
 
{
396
 
        TALLOC_CTX *mem_ctx;
397
 
 
398
 
        ZERO_STRUCTP( priv_set );
399
 
 
400
 
        mem_ctx = talloc_init("privilege set");
401
 
        if ( !mem_ctx ) {
402
 
                DEBUG(0,("privilege_set_init: failed to initialize talloc ctx!\n"));
403
 
                return NT_STATUS_NO_MEMORY;
404
 
        }
405
 
 
406
 
        priv_set->mem_ctx = mem_ctx;
407
 
 
408
 
        return NT_STATUS_OK;
409
 
}
410
 
 
411
 
/****************************************************************************
412
 
  initialise a privilege list and with someone else's talloc context
413
 
****************************************************************************/
414
 
 
415
 
NTSTATUS privilege_set_init_by_ctx(TALLOC_CTX *mem_ctx, PRIVILEGE_SET *priv_set)
416
 
{
417
 
        ZERO_STRUCTP( priv_set );
418
 
 
419
 
        priv_set->mem_ctx = mem_ctx;
420
 
        priv_set->ext_ctx = True;
421
 
 
422
 
        return NT_STATUS_OK;
423
 
}
424
 
 
425
 
/****************************************************************************
426
 
 Free all memory used by a PRIVILEGE_SET
427
 
****************************************************************************/
428
 
 
429
 
void privilege_set_free(PRIVILEGE_SET *priv_set)
430
 
{
431
 
        if ( !priv_set )
432
 
                return;
433
 
 
434
 
        if ( !( priv_set->ext_ctx ) )
435
 
                talloc_destroy( priv_set->mem_ctx );
436
 
 
437
 
        ZERO_STRUCTP( priv_set );
438
 
}
439
 
 
440
 
/****************************************************************************
441
 
 duplicate alloc luid_attr
442
 
 ****************************************************************************/
443
 
 
444
 
NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_la, int count)
445
 
{
446
 
        int i;
447
 
 
448
 
        if ( !old_la )
449
 
                return NT_STATUS_OK;
450
 
 
451
 
        if (count) {
452
 
                *new_la = TALLOC_ARRAY(mem_ctx, LUID_ATTR, count);
453
 
                if ( !*new_la ) {
454
 
                        DEBUG(0,("dup_luid_attr: failed to alloc new LUID_ATTR array [%d]\n", count));
455
 
                        return NT_STATUS_NO_MEMORY;
456
 
                }
457
 
        } else {
458
 
                *new_la = NULL;
459
 
        }
460
 
 
461
 
        for (i=0; i<count; i++) {
462
 
                (*new_la)[i].luid.high = old_la[i].luid.high;
463
 
                (*new_la)[i].luid.low = old_la[i].luid.low;
464
 
                (*new_la)[i].attr = old_la[i].attr;
465
 
        }
466
 
 
467
 
        return NT_STATUS_OK;
468
 
}
469
 
 
470
478
/*******************************************************************
471
479
*******************************************************************/
472
480
 
473
 
bool is_privileged_sid( const DOM_SID *sid )
 
481
bool is_privileged_sid( const struct dom_sid *sid )
474
482
{
475
 
        SE_PRIV mask;
 
483
        uint64_t mask;
476
484
 
477
485
        return get_privileges( sid, &mask );
478
486
}
480
488
/*******************************************************************
481
489
*******************************************************************/
482
490
 
483
 
bool grant_all_privileges( const DOM_SID *sid )
 
491
bool grant_all_privileges( const struct dom_sid *sid )
484
492
{
485
 
        SE_PRIV mask;
486
 
 
487
 
        if (!se_priv_put_all_privileges(&mask)) {
488
 
                return False;
489
 
        }
490
 
 
491
 
        return grant_privilege( sid, &mask );
 
493
        uint64_t mask;
 
494
 
 
495
        se_priv_put_all_privileges(&mask);
 
496
 
 
497
        return grant_privilege_bitmap( sid, mask );
492
498
}