~bug-zappers/ubuntu/lucid/samba/bugzapping

« back to all changes in this revision

Viewing changes to testsuite/printing/psec.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-10-15 12:31:58 UTC
  • Revision ID: james.westby@ubuntu.com-20041015123158-aokykzdqkdgy6dfx
Tags: upstream-3.0.7
ImportĀ upstreamĀ versionĀ 3.0.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/Netbios implementation.
 
3
   Version 2.0
 
4
 
 
5
   Printer security permission manipulation.
 
6
 
 
7
   Copyright (C) Tim Potter 2000
 
8
   
 
9
   This program is free software; you can redistribute it and/or modify
 
10
   it under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 2 of the License, or
 
12
   (at your option) any later version.
 
13
   
 
14
   This program is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
   
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with this program; if not, write to the Free Software
 
21
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
22
*/
 
23
 
 
24
/* This program can get or set NT printer security permissions from the 
 
25
   command line.  Usage: psec getsec|setsec printername.  You must have
 
26
   write access to the ntdrivers.tdb file to set permissions and read
 
27
   access to get permissions.
 
28
 
 
29
   For this program to compile using the supplied Makefile.psec, Samba
 
30
   must be configured with the --srcdir option
 
31
 
 
32
   For getsec, output like the following is sent to standard output:
 
33
 
 
34
       S-1-5-21-1067277791-1719175008-3000797951-500
 
35
 
 
36
       1 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-501
 
37
       1 2 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-501
 
38
       0 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-500
 
39
       0 2 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-500
 
40
       0 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-513
 
41
       0 2 0x00020000 S-1-5-21-1067277791-1719175008-3000797951-513
 
42
       0 2 0xe0000000 S-1-1-0
 
43
 
 
44
   The first two lines describe the owner user and owner group of the printer.
 
45
   If either of these lines are blank then the respective owner property is 
 
46
   not set.  The remaining lines list the printer permissions or ACE entries, 
 
47
   one per line.  Each column describes a different property of the ACE:
 
48
 
 
49
       Column    Description
 
50
       -------------------------------------------------------------------
 
51
         1       ACE type (allow/deny etc) defined in rpc_secdes.h
 
52
         2       ACE flags defined in rpc_secdes.h
 
53
         3       ACE mask - printer ACE masks are defined in rpc_spoolss.h
 
54
         4       SID the ACE applies to
 
55
 
 
56
   The above example describes the following permissions in order:
 
57
 
 
58
       - The guest user has No Access to the printer
 
59
       - The domain administrator has Full Access
 
60
       - Domain Users can Manage Documents
 
61
       - Everyone has Print access
 
62
 
 
63
   The setsec command takes the output format but sets the security descriptor
 
64
   appropriately. */
 
65
 
 
66
#include "includes.h"
 
67
 
 
68
TDB_CONTEXT *tdb;
 
69
 
 
70
/* ACE type conversions */
 
71
 
 
72
char *ace_type_to_str(uint ace_type)
 
73
{
 
74
        static fstring temp;
 
75
 
 
76
        switch(ace_type) {
 
77
        case SEC_ACE_TYPE_ACCESS_DENIED:
 
78
                return "DENY";
 
79
        case SEC_ACE_TYPE_ACCESS_ALLOWED:
 
80
                return "ALLOW";
 
81
        }
 
82
 
 
83
        slprintf(temp, sizeof(temp) - 1, "0x%02x", ace_type);
 
84
        return temp;
 
85
}
 
86
 
 
87
uint str_to_ace_type(char *ace_type)
 
88
{
 
89
        if (strcmp(ace_type, "ALLOWED") == 0) 
 
90
                return SEC_ACE_TYPE_ACCESS_ALLOWED;
 
91
 
 
92
        if (strcmp(ace_type, "DENIED") == 0)
 
93
                return SEC_ACE_TYPE_ACCESS_DENIED;
 
94
 
 
95
        return -1;
 
96
}               
 
97
 
 
98
/* ACE mask (permission) conversions */
 
99
 
 
100
char *ace_mask_to_str(uint32 ace_mask)
 
101
{
 
102
        static fstring temp;
 
103
 
 
104
        switch (ace_mask) {
 
105
        case PRINTER_ACE_FULL_CONTROL:
 
106
                return "Full Control";
 
107
        case PRINTER_ACE_MANAGE_DOCUMENTS:
 
108
                return "Manage Documents";
 
109
        case PRINTER_ACE_PRINT:
 
110
                return "Print";
 
111
        }
 
112
 
 
113
        slprintf(temp, sizeof(temp) - 1, "0x%08x", ace_mask);
 
114
        return temp;
 
115
}
 
116
 
 
117
uint32 str_to_ace_mask(char *ace_mask)
 
118
{
 
119
        if (strcmp(ace_mask, "Full Control") == 0) 
 
120
                return PRINTER_ACE_FULL_CONTROL;
 
121
 
 
122
        if (strcmp(ace_mask, "Manage Documents") == 0)
 
123
                return PRINTER_ACE_MANAGE_DOCUMENTS;
 
124
 
 
125
        if (strcmp(ace_mask, "Print") == 0)
 
126
                return PRINTER_ACE_PRINT;
 
127
 
 
128
        return -1;
 
129
}
 
130
 
 
131
/* ACE conversions */
 
132
 
 
133
char *ace_to_str(SEC_ACE *ace)
 
134
{
 
135
        static pstring temp;
 
136
        fstring sidstr;
 
137
 
 
138
        sid_to_string(sidstr, &ace->sid);
 
139
 
 
140
        slprintf(temp, sizeof(temp) - 1, "%s %d %s %s", 
 
141
                 ace_type_to_str(ace->type), ace->flags,
 
142
                 ace_mask_to_str(ace->info.mask), sidstr);
 
143
 
 
144
        return temp;
 
145
}
 
146
 
 
147
void str_to_ace(SEC_ACE *ace, char *ace_str)
 
148
{
 
149
        SEC_ACCESS sa;
 
150
        DOM_SID sid;
 
151
        uint32 mask;
 
152
        uint8 type, flags;
 
153
 
 
154
        init_sec_access(&sa, mask);
 
155
        init_sec_ace(ace, &sid, type, sa, flags);
 
156
}
 
157
 
 
158
/* Get a printer security descriptor */
 
159
 
 
160
int psec_getsec(char *printer)
 
161
{
 
162
        SEC_DESC_BUF *secdesc_ctr = NULL;
 
163
        TALLOC_CTX *mem_ctx = NULL;
 
164
        fstring keystr, sidstr, tdb_path;
 
165
        prs_struct ps;
 
166
        int result = 0, i;
 
167
 
 
168
        ZERO_STRUCT(ps);
 
169
 
 
170
        /* Open tdb for reading */
 
171
 
 
172
        slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb", 
 
173
                 lp_lockdir());
 
174
 
 
175
        tdb = tdb_open(tdb_path, 0, 0, O_RDONLY, 0600);
 
176
 
 
177
        if (!tdb) {
 
178
                printf("psec: failed to open nt drivers database: %s\n",
 
179
                       sys_errlist[errno]);
 
180
                return 1;
 
181
        }
 
182
 
 
183
        /* Get security blob from tdb */
 
184
 
 
185
        slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
 
186
 
 
187
        mem_ctx = talloc_init();
 
188
 
 
189
        if (!mem_ctx) {
 
190
                printf("memory allocation error\n");
 
191
                result = 1;
 
192
                goto done;
 
193
        }
 
194
 
 
195
        if (tdb_prs_fetch(tdb, keystr, &ps, mem_ctx) != 0) {
 
196
                printf("error fetching descriptor for printer %s\n",
 
197
                       printer);
 
198
                /* cannot do a prs_mem_free() when tdb_prs_fetch fails */
 
199
                /* as the prs structure has not been initialized */
 
200
                tdb_close(tdb);
 
201
                talloc_destroy(mem_ctx);
 
202
                return 1;
 
203
        }
 
204
 
 
205
        /* Unpack into security descriptor buffer */
 
206
 
 
207
        if (!sec_io_desc_buf("nt_printing_getsec", &secdesc_ctr, &ps, 1)) {
 
208
                printf("error unpacking sec_desc_buf\n");
 
209
                result = 1;
 
210
                goto done;
 
211
        }
 
212
 
 
213
        /* Print owner and group sid */
 
214
 
 
215
        if (secdesc_ctr->sec->owner_sid) {
 
216
                sid_to_string(sidstr, secdesc_ctr->sec->owner_sid);
 
217
        } else {
 
218
                fstrcpy(sidstr, "");
 
219
        }
 
220
 
 
221
        printf("%s\n", sidstr);
 
222
 
 
223
        if (secdesc_ctr->sec->grp_sid) {
 
224
                sid_to_string(sidstr, secdesc_ctr->sec->grp_sid);
 
225
        } else {
 
226
                fstrcpy(sidstr, "");
 
227
        }
 
228
 
 
229
        printf("%s\n", sidstr);
 
230
 
 
231
        /* Print aces */
 
232
 
 
233
        if (!secdesc_ctr->sec->dacl) {
 
234
                result = 0;
 
235
                goto done;
 
236
        }
 
237
 
 
238
        for (i = 0; i < secdesc_ctr->sec->dacl->num_aces; i++) {
 
239
                SEC_ACE *ace = &secdesc_ctr->sec->dacl->ace[i];
 
240
 
 
241
                sid_to_string(sidstr, &ace->sid);
 
242
 
 
243
                printf("%d %d 0x%08x %s\n", ace->type, ace->flags,
 
244
                       ace->info.mask, sidstr);
 
245
        }
 
246
 
 
247
 done:
 
248
        if (tdb) tdb_close(tdb);
 
249
        if (mem_ctx) talloc_destroy(mem_ctx);
 
250
        if (secdesc_ctr) free_sec_desc_buf(&secdesc_ctr);
 
251
        prs_mem_free(&ps);
 
252
 
 
253
        return result;
 
254
}
 
255
 
 
256
/* Set a printer security descriptor */
 
257
 
 
258
int psec_setsec(char *printer)
 
259
{
 
260
        DOM_SID user_sid, group_sid;
 
261
        SEC_ACE *ace_list = NULL;
 
262
        SEC_ACL *dacl = NULL;
 
263
        SEC_DESC *sd;
 
264
        SEC_DESC_BUF *sdb = NULL;
 
265
        int result = 0, num_aces = 0;
 
266
        fstring line, keystr, tdb_path;
 
267
        size_t size;
 
268
        prs_struct ps;
 
269
        TALLOC_CTX *mem_ctx = NULL;
 
270
        BOOL has_user_sid = False, has_group_sid = False;
 
271
 
 
272
        ZERO_STRUCT(ps);
 
273
 
 
274
        /* Open tdb for reading */
 
275
 
 
276
        slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb", 
 
277
                 lp_lockdir());
 
278
 
 
279
        tdb = tdb_open(tdb_path, 0, 0, O_RDWR, 0600);
 
280
 
 
281
        if (!tdb) {
 
282
                printf("psec: failed to open nt drivers database: %s\n",
 
283
                       sys_errlist[errno]);
 
284
                result = 1;
 
285
                goto done;
 
286
        }
 
287
 
 
288
        /* Read owner and group sid */
 
289
 
 
290
        fgets(line, sizeof(fstring), stdin);
 
291
        if (line[0] != '\n') {
 
292
                string_to_sid(&user_sid, line);
 
293
                has_user_sid = True;
 
294
        }
 
295
 
 
296
        fgets(line, sizeof(fstring), stdin);
 
297
        if (line[0] != '\n') {
 
298
                string_to_sid(&group_sid, line);
 
299
                has_group_sid = True;
 
300
        }
 
301
 
 
302
        /* Read ACEs from standard input for discretionary ACL */
 
303
 
 
304
        while(fgets(line, sizeof(fstring), stdin)) {
 
305
                int ace_type, ace_flags;
 
306
                uint32 ace_mask;
 
307
                fstring sidstr;
 
308
                DOM_SID sid;
 
309
                SEC_ACCESS sa;
 
310
 
 
311
                if (sscanf(line, "%d %d 0x%x %s", &ace_type, &ace_flags, 
 
312
                           &ace_mask, sidstr) != 4) {
 
313
                        continue;
 
314
                }
 
315
 
 
316
                string_to_sid(&sid, sidstr);
 
317
                
 
318
                ace_list = Realloc(ace_list, sizeof(SEC_ACE) * 
 
319
                                   (num_aces + 1));
 
320
                
 
321
                init_sec_access(&sa, ace_mask);
 
322
                init_sec_ace(&ace_list[num_aces], &sid, ace_type, sa, 
 
323
                             ace_flags);
 
324
 
 
325
                num_aces++;
 
326
        }
 
327
 
 
328
        dacl = make_sec_acl(ACL_REVISION, num_aces, ace_list);
 
329
        free(ace_list);
 
330
 
 
331
        /* Create security descriptor */
 
332
 
 
333
        sd = make_sec_desc(SEC_DESC_REVISION,
 
334
                           has_user_sid ? &user_sid : NULL, 
 
335
                           has_group_sid ? &group_sid : NULL,
 
336
                           NULL, /* System ACL */
 
337
                           dacl, /* Discretionary ACL */
 
338
                           &size);
 
339
 
 
340
        free_sec_acl(&dacl);
 
341
 
 
342
        sdb = make_sec_desc_buf(size, sd);
 
343
 
 
344
        free_sec_desc(&sd);
 
345
 
 
346
        /* Write security descriptor to tdb */
 
347
 
 
348
        mem_ctx = talloc_init();
 
349
 
 
350
        if (!mem_ctx) {
 
351
                printf("memory allocation error\n");
 
352
                result = 1;
 
353
                goto done;
 
354
        }
 
355
 
 
356
        prs_init(&ps, (uint32)sec_desc_size(sdb->sec) + 
 
357
                 sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
 
358
 
 
359
        if (!sec_io_desc_buf("nt_printing_setsec", &sdb, &ps, 1)) {
 
360
                printf("sec_io_desc_buf failed\n");
 
361
                goto done;
 
362
        }
 
363
 
 
364
        slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
 
365
 
 
366
        if (!tdb_prs_store(tdb, keystr, &ps)==0) {
 
367
                printf("Failed to store secdesc for %s\n", printer);
 
368
                goto done;
 
369
        }
 
370
 
 
371
 done:
 
372
        if (tdb) tdb_close(tdb);
 
373
        if (sdb) free_sec_desc_buf(&sdb);
 
374
        if (mem_ctx) talloc_destroy(mem_ctx);
 
375
        prs_mem_free(&ps);
 
376
 
 
377
        return result;
 
378
}
 
379
 
 
380
/* Help */
 
381
 
 
382
void usage(void)
 
383
{
 
384
        printf("Usage: psec getsec|setsec printername\n");
 
385
}
 
386
 
 
387
/* Main function */
 
388
 
 
389
int main(int argc, char **argv)
 
390
{
 
391
        pstring servicesf = CONFIGFILE;
 
392
 
 
393
        /* Argument check */
 
394
 
 
395
        if (argc == 1) {
 
396
                usage();
 
397
                return 1;
 
398
        }
 
399
 
 
400
        /* Load smb.conf file */
 
401
 
 
402
        charset_initialise();
 
403
 
 
404
        if (!lp_load(servicesf,False,False,True)) {
 
405
                fprintf(stderr, "Couldn't load confiuration file %s\n",
 
406
                        servicesf);
 
407
                return 1;
 
408
        }
 
409
 
 
410
        /* Do commands */
 
411
 
 
412
        if (strcmp(argv[1], "setsec") == 0) {
 
413
 
 
414
                if (argc != 3) {
 
415
                        usage();
 
416
                        return 1;
 
417
                }
 
418
 
 
419
                return psec_setsec(argv[2]);
 
420
        }
 
421
 
 
422
        if (strcmp(argv[1], "getsec") == 0) {
 
423
 
 
424
                if (argc != 3) {
 
425
                        usage();
 
426
                        return 1;
 
427
                }
 
428
 
 
429
                return psec_getsec(argv[2]);
 
430
        }
 
431
 
 
432
        /* An unknown command */
 
433
 
 
434
        printf("psec: unknown command %s\n", argv[1]);
 
435
        return 1;
 
436
}