~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to testsuite/printing/psec.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

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
 
}