~ubuntu-branches/debian/sid/ntfs-3g/sid

« back to all changes in this revision

Viewing changes to .pc/0001-type-inconsistencies.patch/src/usermap.c

  • Committer: Package Import Robot
  • Author(s): Daniel Baumann
  • Date: 2014-06-11 07:05:11 UTC
  • Revision ID: package-import@ubuntu.com-20140611070511-uff0av8cy0p2j3ty
Tags: 1:2014.2.15AR.1-2
* Adding patch from upstream to fix type inconsistencies in
  ntfs_initialize_file_security (Closes: #749517).
* Moving undocumented ntfsdump_logfile, ntfsmftalloc, and ntfsck to
  ntfs-3g-dev (Closes: #747872).
* Adding patch from upstream to correct exit values (Closes: #741992).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *               Windows to Linux user mapping for ntfs-3g
 
3
 *
 
4
 * 
 
5
 * Copyright (c) 2007-2008 Jean-Pierre Andre
 
6
 *
 
7
 *    A quick'n dirty program scanning owners of files in
 
8
 *      "c:\Documents and Settings" (and "c:\Users")
 
9
 *     and asking user to map them to Linux accounts
 
10
 *
 
11
 *          History
 
12
 *
 
13
 *  Sep 2007
 
14
 *     - first version, limited to Win32
 
15
 *
 
16
 *  Oct 2007
 
17
 *     - ported to Linux (rewritten would be more correct)
 
18
 *
 
19
 *  Nov 2007 Version 1.0.0
 
20
 *     - added more defaults
 
21
 *
 
22
 *  Nov 2007 Version 1.0.1
 
23
 *     - avoided examining files whose name begin with a '$'
 
24
 *
 
25
 *  Jan 2008 Version 1.0.2
 
26
 *     - moved user mapping file to directory .NTFS-3G (hidden for Linux)
 
27
 *     - fixed an error case in Windows version
 
28
 *
 
29
 *  Nov 2008 Version 1.1.0
 
30
 *     - fixed recursions for account in Linux version
 
31
 *     - searched owner in c:\Users (standard location for Vista)
 
32
 *
 
33
 *  May 2009 Version 1.1.1
 
34
 *     - reordered mapping records to limit usage of same SID for user and group
 
35
 *     - fixed decoding SIDs on 64-bit systems
 
36
 *     - fixed a pointer to dynamic data in mapping tables
 
37
 *     - fixed default mapping on Windows
 
38
 *     - fixed bug for renaming UserMapping on Windows
 
39
 *
 
40
 *  May 2009 Version 1.1.2
 
41
 *     - avoided selecting DOS names on Linux
 
42
 *
 
43
 *  Nov 2009 Version 1.1.3
 
44
 *     - shutdown compiler warnings for unused parameters
 
45
 *
 
46
 *  Jan 2010 Version 1.1.4
 
47
 *     - fixed compilation problems for Mac OSX (Erik Larsson)
 
48
 */
 
49
 
 
50
/*
 
51
 * This program is free software; you can redistribute it and/or modify
 
52
 * it under the terms of the GNU General Public License as published by
 
53
 * the Free Software Foundation; either version 2 of the License, or
 
54
 * (at your option) any later version.
 
55
 *
 
56
 * This program is distributed in the hope that it will be useful,
 
57
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
58
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
59
 * GNU General Public License for more details.
 
60
 *
 
61
 * You should have received a copy of the GNU General Public License
 
62
 * along with this program (in the main directory of the NTFS-3G
 
63
 * distribution in the file COPYING); if not, write to the Free Software
 
64
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
65
 */
 
66
 
 
67
/*
 
68
 *              General parameters which may have to be adapted to needs
 
69
 */
 
70
 
 
71
#ifdef HAVE_CONFIG_H
 
72
#define USESTUBS 1 /* API stubs generated at link time */
 
73
#else
 
74
#define USESTUBS 0 /* direct calls to API, based on following definitions */
 
75
#define ENVNTFS3G "NTFS3G"
 
76
#define LIBFILE64 "/lib64/libntfs-3g.so.851"
 
77
#define LIBFILE "/lib/libntfs-3g.so.851"
 
78
#endif
 
79
 
 
80
#define GET_FILE_SECURITY "ntfs_get_file_security"
 
81
#define SET_FILE_SECURITY "ntfs_set_file_security"
 
82
#define READ_DIRECTORY "ntfs_read_directory"
 
83
#define INIT_FILE_SECURITY "ntfs_initialize_file_security"
 
84
#define LEAVE_FILE_SECURITY "ntfs_leave_file_security"
 
85
 
 
86
#define VERSION "1.1.4"
 
87
#define MAPDIR ".NTFS-3G"
 
88
#define MAPFILE "UserMapping"
 
89
#define MAXATTRSZ 2048
 
90
#define MAXSIDSZ 80
 
91
#define MAXNAMESZ 256
 
92
#define OWNERS1 "Documents and Settings"
 
93
#define OWNERS2 "Users"
 
94
 
 
95
/*
 
96
 *              Define WIN32 for a Windows execution
 
97
 *      may have to be adapted to compiler or something else
 
98
 */
 
99
 
 
100
#ifndef WIN32
 
101
#if defined(__WIN32) | defined(__WIN32__) | defined(WNSC)
 
102
#define WIN32 1
 
103
#endif
 
104
#endif
 
105
 
 
106
#ifdef WIN32
 
107
#define BANNER "Generated by usermap for Windows, v " VERSION
 
108
#else
 
109
#define BANNER "Generated by usermap for Linux, v " VERSION
 
110
#endif
 
111
 
 
112
 
 
113
#include <stdio.h>
 
114
#include <string.h>
 
115
#include <stdlib.h>
 
116
#include <fcntl.h>
 
117
#include <sys/types.h>
 
118
#include <sys/stat.h>
 
119
#include <errno.h>
 
120
 
 
121
/*
 
122
 *      Define the security API according to platform
 
123
 */
 
124
 
 
125
#ifdef WIN32
 
126
 
 
127
#include <fcntl.h>
 
128
#include <windows.h>
 
129
 
 
130
#define STATIC
 
131
 
 
132
typedef enum { DENIED, AGREED } boolean;
 
133
 
 
134
#else
 
135
 
 
136
#include <unistd.h>
 
137
#include <dlfcn.h>
 
138
 
 
139
typedef enum { DENIED, AGREED } boolean, BOOL;
 
140
typedef unsigned int DWORD; /* must be 32 bits whatever the platform */
 
141
typedef DWORD *LPDWORD;
 
142
 
 
143
enum {  OWNER_SECURITY_INFORMATION = 1,
 
144
        GROUP_SECURITY_INFORMATION = 2,
 
145
        DACL_SECURITY_INFORMATION = 4,
 
146
        SACL_SECURITY_INFORMATION = 8
 
147
} ;
 
148
 
 
149
struct CALLBACK {
 
150
        const char *accname;
 
151
        const char *dir;
 
152
        int levels;
 
153
        int docset;
 
154
} ;
 
155
 
 
156
typedef int (*dircallback)(struct CALLBACK *context, char *ntfsname,
 
157
        int length, int type, long long pos, unsigned long long mft_ref,
 
158
        unsigned int dt_type);
 
159
 
 
160
#if USESTUBS
 
161
 
 
162
#define STATIC static
 
163
 
 
164
BOOL ntfs_get_file_security(void *scapi,
 
165
                const char *path, DWORD selection,
 
166
                char *buf, DWORD buflen, LPDWORD psize);
 
167
BOOL ntfs_set_file_security(void *scapi,
 
168
                const char *path, DWORD selection, const char *attr);
 
169
BOOL ntfs_read_directory(void *scapi,
 
170
                const char *path, dircallback callback, void *context);
 
171
void *ntfs_initialize_file_security(const char *device,
 
172
                                int flags);
 
173
BOOL ntfs_leave_file_security(void *scapi);
 
174
 
 
175
#else
 
176
 
 
177
#define STATIC
 
178
 
 
179
BOOL (*ntfs_get_file_security)(void *scapi,
 
180
                const char *path, DWORD selection,
 
181
                char *buf, DWORD buflen, LPDWORD psize);
 
182
BOOL (*ntfs_set_file_security)(void *scapi,
 
183
                const char *path, DWORD selection, const char *attr);
 
184
BOOL (*ntfs_read_directory)(void *scapi,
 
185
                const char *path, dircallback callback, void *context);
 
186
void *(*ntfs_initialize_file_security)(const char *device,
 
187
                                int flags);
 
188
BOOL (*ntfs_leave_file_security)(void *scapi);
 
189
 
 
190
#endif
 
191
 
 
192
STATIC boolean open_security_api(void);
 
193
STATIC boolean close_security_api(void);
 
194
STATIC boolean open_volume(const char *volume);
 
195
STATIC boolean close_volume(const char *volume);
 
196
 
 
197
#endif
 
198
 
 
199
struct MAPPING {
 
200
        struct MAPPING *next;
 
201
        const char *uidstr;
 
202
        const char *gidstr;
 
203
        const char *sidstr;
 
204
        const unsigned char *sid;
 
205
        const char *login;
 
206
        boolean defined;
 
207
};
 
208
 
 
209
struct MAPPING *firstmapping;
 
210
struct MAPPING *lastmapping;
 
211
 
 
212
#ifdef WIN32
 
213
char *currentwinname;
 
214
char *currentdomain;
 
215
unsigned char *currentsid;
 
216
#endif
 
217
 
 
218
#ifndef WIN32
 
219
 
 
220
void *ntfs_handle;
 
221
void *ntfs_context = (void*)NULL;
 
222
 
 
223
/*
 
224
 *              Shut down compiler warnings for unused parameters
 
225
 */
 
226
 
 
227
static long unused(const void *p)
 
228
{
 
229
return ((long)p);
 
230
}
 
231
 
 
232
/*
 
233
 *              Open and close the security API (platform dependent)
 
234
 */
 
235
 
 
236
STATIC boolean open_security_api(void)
 
237
{
 
238
#if USESTUBS
 
239
        return (AGREED);
 
240
#else
 
241
        char *error;
 
242
        boolean err;
 
243
        const char *libfile;
 
244
 
 
245
        err = AGREED;
 
246
        libfile = getenv(ENVNTFS3G);
 
247
        if (!libfile)
 
248
                libfile = (sizeof(char*) == 8 ? LIBFILE64 : LIBFILE);
 
249
        ntfs_handle = dlopen(libfile,RTLD_LAZY);
 
250
        if (ntfs_handle) {
 
251
                ntfs_initialize_file_security =
 
252
                                dlsym(ntfs_handle,INIT_FILE_SECURITY);
 
253
                error = dlerror();
 
254
                if (error)
 
255
                        fprintf(stderr," %s\n",error);
 
256
                else {
 
257
                        ntfs_leave_file_security =
 
258
                                        dlsym(ntfs_handle,LEAVE_FILE_SECURITY);
 
259
                        ntfs_get_file_security =
 
260
                                        dlsym(ntfs_handle,GET_FILE_SECURITY);
 
261
                        ntfs_set_file_security =
 
262
                                        dlsym(ntfs_handle,SET_FILE_SECURITY);
 
263
                        ntfs_read_directory =
 
264
                                        dlsym(ntfs_handle,READ_DIRECTORY);
 
265
                        err = !ntfs_initialize_file_security
 
266
                                || !ntfs_leave_file_security
 
267
                                || !ntfs_get_file_security
 
268
                                || !ntfs_set_file_security
 
269
                                || !ntfs_read_directory;
 
270
                        if (error)
 
271
                                fprintf(stderr,"ntfs-3g API not available\n");
 
272
                }
 
273
        } else {
 
274
                fprintf(stderr,"Could not open ntfs-3g library\n");
 
275
                fprintf(stderr,"\nPlease set environment variable \"" ENVNTFS3G "\"\n");
 
276
                fprintf(stderr,"to appropriate path and retry\n");
 
277
        }
 
278
        return (!err);
 
279
#endif
 
280
}
 
281
 
 
282
STATIC boolean close_security_api(void)
 
283
{
 
284
#if USESTUBS
 
285
        return (0);
 
286
#else
 
287
        return (!dlclose(ntfs_handle));
 
288
#endif
 
289
}
 
290
 
 
291
/*
 
292
 *              Open and close a volume (platform dependent)
 
293
 *      assuming a single volume needs to be opened at any time
 
294
 */
 
295
 
 
296
STATIC boolean open_volume(const char *volume)
 
297
{
 
298
        boolean ok;
 
299
 
 
300
        ok = DENIED;
 
301
        if (!ntfs_context) {
 
302
                ntfs_context = ntfs_initialize_file_security(volume,0);
 
303
                if (ntfs_context) {
 
304
                        fprintf(stderr,"\"%s\" opened\n",volume);
 
305
                        ok = AGREED;
 
306
                } else {
 
307
                        fprintf(stderr,"Could not open \"%s\"\n",volume);
 
308
                        fprintf(stderr,"Make sure \"%s\" is not mounted\n",volume);
 
309
                }
 
310
        } else
 
311
                fprintf(stderr,"A volume is already open\n");
 
312
        return (ok);
 
313
}
 
314
 
 
315
STATIC boolean close_volume(const char *volume)
 
316
{
 
317
        boolean r;
 
318
 
 
319
        r = ntfs_leave_file_security(ntfs_context);
 
320
        if (r)
 
321
                fprintf(stderr,"\"%s\" closed\n",volume);
 
322
        else
 
323
                fprintf(stderr,"Could not close \"%s\"\n",volume);
 
324
        ntfs_context = (void*)NULL;
 
325
        return (r);
 
326
}
 
327
 
 
328
/*
 
329
 *              A poor man's conversion of Unicode to UTF8
 
330
 *      We are assuming outputs to terminal expect UTF8
 
331
 */
 
332
 
 
333
STATIC void to_utf8(char *dst, const char *src, unsigned int cnt)
 
334
{
 
335
        unsigned int ch;
 
336
        unsigned int i;
 
337
 
 
338
        for (i=0; i<cnt; i++) {
 
339
                ch = *src++ & 255;
 
340
                ch += (*src++ & 255) << 8;
 
341
                if (ch < 0x80)
 
342
                        *dst++ = ch;
 
343
                else
 
344
                        if (ch < 0x1000) {
 
345
                                *dst++ = 0xc0 + (ch >> 6);
 
346
                                *dst++ = 0x80 + (ch & 63);
 
347
                        } else {
 
348
                                *dst++ = 0xe0 + (ch >> 12);
 
349
                                *dst++ = 0x80 + ((ch >> 6) & 63);
 
350
                                *dst++ = 0x80 + (ch & 63);
 
351
                        }
 
352
        }
 
353
        *dst = 0;
 
354
}
 
355
 
 
356
STATIC int utf8_size(const char *src, unsigned int cnt)
 
357
{
 
358
        unsigned int ch;
 
359
        unsigned int i;
 
360
        int size;
 
361
 
 
362
        size = 0;
 
363
        for (i=0; i<cnt; i++) {
 
364
                ch = *src++ & 255;
 
365
                ch += (*src++ & 255) << 8;
 
366
                if (ch < 0x80)
 
367
                        size++;
 
368
                else
 
369
                        if (ch < 0x1000)
 
370
                                size += 2;
 
371
                        else
 
372
                                size += 3;
 
373
        }
 
374
        return (size);
 
375
}
 
376
 
 
377
#endif
 
378
 
 
379
 
 
380
STATIC void welcome(void)
 
381
{
 
382
        printf("\nThis tool will help you to build a mapping of Windows users\n");
 
383
        printf("to Linux users.\n");
 
384
        printf("Be prepared to give Linux user id (uid) and group id (gid)\n");
 
385
        printf("for owners of files which will be selected.\n");
 
386
}
 
387
 
 
388
STATIC unsigned int get2l(const unsigned char *attr, int p)
 
389
{
 
390
        int i;
 
391
        unsigned int v;
 
392
 
 
393
        v = 0;
 
394
        for (i = 0; i < 2; i++)
 
395
                v += (attr[p + i] & 255) << (8 * i);
 
396
        return (v);
 
397
}
 
398
 
 
399
STATIC unsigned long get4l(const unsigned char *attr, int p)
 
400
{
 
401
        int i;
 
402
        unsigned long v;
 
403
 
 
404
        v = 0;
 
405
        for (i = 0; i < 4; i++)
 
406
                v += (attr[p + i] & 255L) << (8 * i);
 
407
        return (v);
 
408
}
 
409
 
 
410
STATIC unsigned long long get6h(const unsigned char *attr, int p)
 
411
{
 
412
        int i;
 
413
        unsigned long long v;
 
414
 
 
415
        v = 0;
 
416
        for (i = 0; i < 6; i++)
 
417
                v = (v << 8) + (attr[p + i] & 255L);
 
418
        return (v);
 
419
}
 
420
 
 
421
STATIC char *decodesid(const unsigned char *sid)
 
422
{
 
423
        char *str;
 
424
        int i;
 
425
        unsigned long long auth;
 
426
        unsigned long subauth;
 
427
 
 
428
        str = (char *)malloc(MAXSIDSZ);
 
429
        if (str) {
 
430
                strcpy(str, "S");
 
431
                sprintf(&str[strlen(str)], "-%d", sid[0]);      /* revision */
 
432
                auth = get6h(sid, 2);
 
433
#ifdef WIN32
 
434
                sprintf(&str[strlen(str)], "-%I64u", auth);     /* main authority */
 
435
#else
 
436
                sprintf(&str[strlen(str)], "-%llu", auth);      /* main authority */
 
437
#endif
 
438
                for (i = 0; (i < 8) && (i < sid[1]); i++) {
 
439
                        subauth = get4l(sid, 8 + 4 * i);
 
440
                        sprintf(&str[strlen(str)], "-%lu", subauth);    /* sub-authority */
 
441
                }
 
442
        }
 
443
        return (str);
 
444
}
 
445
 
 
446
/*
 
447
 *        Test whether a generic group (S-1-5-21- ... -513)
 
448
 */
 
449
 
 
450
STATIC boolean isgenericgroup(const char *sid)
 
451
{
 
452
        boolean yes;
 
453
 
 
454
        yes = !strncmp(sid,"S-1-5-21-",9)
 
455
                && !strcmp(strrchr(sid,'-'),"-513");
 
456
        return (yes);
 
457
}
 
458
 
 
459
STATIC unsigned char *makegroupsid(const unsigned char *sid)
 
460
{
 
461
        static unsigned char groupsid[MAXSIDSZ];
 
462
        int size;
 
463
 
 
464
        size = 8 + 4*sid[1];
 
465
        memcpy(groupsid, sid, size);
 
466
                /* replace last level by 513 */
 
467
        groupsid[size - 4] = 1;
 
468
        groupsid[size - 3] = 2;
 
469
        groupsid[size - 2] = 0;
 
470
        groupsid[size - 1] = 0;
 
471
        return (groupsid);
 
472
}
 
473
 
 
474
STATIC void domapping(const char *accname, const char *filename,
 
475
                const unsigned char *sid, int type)
 
476
{
 
477
        char buf[81];
 
478
        char *sidstr;
 
479
        char *idstr;
 
480
        int sidsz;
 
481
        boolean reject;
 
482
        struct MAPPING *mapping;
 
483
        char *login;
 
484
        char *p;
 
485
 
 
486
        if ((get6h(sid, 2) == 5) && (get4l(sid, 8) == 21)) {
 
487
                sidstr = decodesid(sid);
 
488
                mapping = firstmapping;
 
489
                while (mapping && strcmp(mapping->sidstr, sidstr))
 
490
                        mapping = mapping->next;
 
491
                if (mapping
 
492
                    && (mapping->defined
 
493
                         || !accname
 
494
                         || !strcmp(mapping->login, accname)))
 
495
                        free(sidstr);   /* decision already known */
 
496
                else {
 
497
                        do {
 
498
                                reject = DENIED;
 
499
                                printf("\n");
 
500
                                if (accname)
 
501
                                        printf("Under Windows login \"%s\"\n", accname);
 
502
                                printf("   file \"%s\" has no mapped %s\n",
 
503
                                               filename,(type ? "group" : "owner"));
 
504
                                printf("By which Linux login should this file be owned ?\n");
 
505
                                printf("Enter %s of login, or just press \"enter\" if this file\n",
 
506
                                        (type ? "gid" : "uid"));
 
507
                                printf("does not belong to a user, or you do not known to whom\n");
 
508
                                printf("\n");
 
509
                                if (type)
 
510
                                        printf("Group : ");
 
511
                                else
 
512
                                        printf("User : ");
 
513
                                p = fgets(buf, 80, stdin);
 
514
                                if (p && p[0] && (p[strlen(p) - 1] == '\n'))
 
515
                                        p[strlen(p) - 1] = '\0';
 
516
 
 
517
                                if (p && p[0]
 
518
                                         && ((p[0] == '0') || !strcmp(p, "root"))) {
 
519
                                        printf("Please do not map users to root\n");
 
520
                                        printf("Administrators will be mapped automatically\n");
 
521
                                        reject = AGREED;
 
522
                                }
 
523
                                if (reject)
 
524
                                        printf("Please retry\n");
 
525
                        } while (reject);
 
526
                        if (!mapping) {
 
527
                                mapping =
 
528
                                    (struct MAPPING *)
 
529
                                    malloc(sizeof(struct MAPPING));
 
530
                                mapping->next = (struct MAPPING *)NULL;
 
531
                                mapping->defined = DENIED;
 
532
                                if (lastmapping)
 
533
                                        lastmapping->next = mapping;
 
534
                                else
 
535
                                        firstmapping = mapping;
 
536
                                lastmapping = mapping;
 
537
                        }
 
538
                        if (mapping) {
 
539
                                if (p && p[0]) {
 
540
                                        idstr = (char *)malloc(strlen(p) + 1);
 
541
                                        if (idstr) {
 
542
                                                strcpy(idstr, p);
 
543
                                                if (type) {
 
544
                                                        mapping->uidstr = "";
 
545
                                                        mapping->gidstr = idstr;
 
546
                                                } else {
 
547
                                                        mapping->uidstr = idstr;
 
548
                                                        mapping->gidstr = idstr;
 
549
                                                }
 
550
                                                mapping->defined = AGREED;
 
551
                                        }
 
552
                                }
 
553
                                mapping->sidstr = sidstr;
 
554
                                if (accname) {
 
555
                                        login = (char*)malloc(strlen(accname) + 1);
 
556
                                        if (login)
 
557
                                                strcpy(login,accname);
 
558
                                        mapping->login = login;
 
559
                                } else
 
560
                                        mapping->login = (char*)NULL;
 
561
                                sidsz = 8 + sid[1]*4;
 
562
                                p = (char*)malloc(sidsz);
 
563
                                if (p) {
 
564
                                        memcpy(p, sid, sidsz);
 
565
                                }
 
566
                                mapping->sid = (unsigned char*)p;
 
567
                        }
 
568
                }
 
569
        }
 
570
}
 
571
 
 
572
STATIC void listaclusers(const char *accname, const unsigned char *attr, int off)
 
573
{
 
574
        int i;
 
575
        int cnt;
 
576
        int x;
 
577
 
 
578
        cnt = get2l(attr, off + 4);
 
579
        x = 8;
 
580
        for (i = 0; i < cnt; i++) {
 
581
                domapping(accname, (char *)NULL, &attr[off + x + 8], 2);
 
582
                x += get2l(attr, off + x + 2);
 
583
        }
 
584
}
 
585
 
 
586
#ifdef WIN32
 
587
 
 
588
STATIC void account(const char *accname, const char *dir, const char *name, int type)
 
589
{
 
590
        unsigned char attr[MAXATTRSZ];
 
591
        unsigned long attrsz;
 
592
        char *fullname;
 
593
        int attrib;
 
594
 
 
595
        fullname = (char *)malloc(strlen(dir) + strlen(name) + 2);
 
596
        if (fullname) {
 
597
                strcpy(fullname, dir);
 
598
                strcat(fullname, "\\");
 
599
                strcat(fullname, name);
 
600
                attrib = GetFileAttributes(fullname);
 
601
                if (attrib & 0x10) {    /* only directories processed */
 
602
                        if (GetFileSecurity
 
603
                            (fullname, OWNER_SECURITY_INFORMATION, attr, MAXATTRSZ,
 
604
                             &attrsz)) {
 
605
                                domapping(accname, name, &attr[20], 0);
 
606
                                attrsz = 0;
 
607
                                if (GetFileSecurity
 
608
                                    (fullname, GROUP_SECURITY_INFORMATION, attr,
 
609
                                     MAXATTRSZ, &attrsz))
 
610
                                        domapping(accname, name, &attr[20], 1);
 
611
                                else
 
612
                                        printf("   No group SID\n");
 
613
                                attrsz = 0;
 
614
                                if (GetFileSecurityA
 
615
                                    (fullname, DACL_SECURITY_INFORMATION, attr,
 
616
                                     MAXATTRSZ, &attrsz)) {
 
617
                                        if (type == 0)
 
618
                                                listaclusers(accname, attr, 20);
 
619
                                } else
 
620
                                        printf
 
621
                                            ("   No discretionary access control list\n");
 
622
                        }
 
623
                }
 
624
        free(fullname);
 
625
        }
 
626
}
 
627
 
 
628
#else
 
629
 
 
630
STATIC void account(const char *accname, const char *dir, const char *name, int type)
 
631
{
 
632
        unsigned char attr[MAXATTRSZ];
 
633
        DWORD attrsz;
 
634
        char *fullname;
 
635
 
 
636
        fullname = (char *)malloc(strlen(dir) + strlen(name) + 2);
 
637
        if (fullname) {
 
638
                strcpy(fullname, dir);
 
639
                strcat(fullname, "/");
 
640
                strcat(fullname, name);
 
641
                if (ntfs_get_file_security(ntfs_context,
 
642
                        fullname, OWNER_SECURITY_INFORMATION,
 
643
                        (char*)attr, MAXATTRSZ, &attrsz)) {
 
644
                        domapping(accname, name, &attr[20], 0);
 
645
                        attrsz = 0;
 
646
                        if (ntfs_get_file_security(ntfs_context,
 
647
                             fullname, GROUP_SECURITY_INFORMATION,
 
648
                             (char*)attr, MAXATTRSZ, &attrsz))
 
649
                                domapping(accname, name, &attr[20], 1);
 
650
                        else
 
651
                                printf("   No group SID\n");
 
652
                        attrsz = 0;
 
653
                        if (ntfs_get_file_security(ntfs_context,
 
654
                             fullname, DACL_SECURITY_INFORMATION,
 
655
                             (char*)attr, MAXATTRSZ, &attrsz)) {
 
656
                                if (type == 0)
 
657
                                        listaclusers(accname, attr, 20);
 
658
                        } else
 
659
                                printf("   No discretionary access control list for %s !\n",
 
660
                                        dir);
 
661
                }
 
662
        free(fullname);
 
663
        }
 
664
}
 
665
 
 
666
#endif
 
667
 
 
668
 
 
669
/*
 
670
 *              recursive search of file owners and groups in a directory
 
671
 */
 
672
 
 
673
#ifdef WIN32
 
674
 
 
675
STATIC boolean recurse(const char *accname, const char *dir, int levels)
 
676
{
 
677
        WIN32_FIND_DATA found;
 
678
        HANDLE search;
 
679
        char *filter;
 
680
        char *fullname;
 
681
        boolean err;
 
682
 
 
683
        err = DENIED;
 
684
        filter = (char *)malloc(strlen(dir) + 5);
 
685
        if (filter) {
 
686
                strcpy(filter, dir);
 
687
                strcat(filter, "\\*.*");
 
688
                search = FindFirstFile(filter, &found);
 
689
                if (search != INVALID_HANDLE_VALUE) {
 
690
                        do {
 
691
                                if (found.cFileName[0] != '.') {
 
692
                                        account(accname, dir, found.cFileName,1);
 
693
                                        if (levels > 0) {
 
694
                                                fullname =
 
695
                                                    (char *)malloc(strlen(dir) +
 
696
                                                                   strlen(found.cFileName)
 
697
                                                                   + 2);
 
698
                                                if (fullname) {
 
699
                                                        strcpy(fullname, dir);
 
700
                                                        strcat(fullname, "\\");
 
701
                                                        strcat(fullname,
 
702
                                                               found.cFileName);
 
703
                                                        recurse(accname,
 
704
                                                                fullname,
 
705
                                                                levels - 1);
 
706
                                                        free(fullname);
 
707
                                                }
 
708
                                        }
 
709
                                }
 
710
                        } while (FindNextFile(search, &found));
 
711
                        FindClose(search);
 
712
                }
 
713
                free(filter);
 
714
        } else {
 
715
                printf("Directory %s not found\n",dir);
 
716
                err = AGREED;
 
717
        }
 
718
        return (!err);
 
719
}
 
720
 
 
721
#else
 
722
 
 
723
STATIC boolean recurse(const char *accname, const char *dir, int levels, int docset);
 
724
 
 
725
STATIC int callback(struct CALLBACK *context, char *ntfsname,
 
726
        int length, int type, long long pos, unsigned long long mft_ref,
 
727
        unsigned int dt_type)
 
728
{
 
729
        char *fullname;
 
730
        char *accname;
 
731
        char *name;
 
732
 
 
733
        unused((void*)&pos);
 
734
        unused((void*)&mft_ref);
 
735
        unused((void*)&dt_type);
 
736
        fullname = (char *)malloc(strlen(context->dir)
 
737
                         + utf8_size(ntfsname, length) + 2);
 
738
        if (fullname) {
 
739
                if (strcmp(context->dir,"/")) {
 
740
                        strcpy(fullname, context->dir);
 
741
                        strcat(fullname, "/");
 
742
                } else
 
743
                        strcpy(fullname,"/");
 
744
                        /* Unicode to ascii conversion by a lazy man */
 
745
                name = &fullname[strlen(fullname)];
 
746
                to_utf8(name, ntfsname, length);
 
747
                        /* ignore special files and DOS names */
 
748
                if ((type != 2)
 
749
                   && strcmp(name,".")
 
750
                   && strcmp(name,"..")
 
751
                   && (name[0] != '$')) {
 
752
                        switch (context->docset) {
 
753
                        case 2 :
 
754
                                        /*
 
755
                                         * only "Documents and Settings"
 
756
                                         * or "Users"
 
757
                                         */
 
758
                                if (!strcmp(name,OWNERS1)
 
759
                                   || !strcmp(name,OWNERS2)) {
 
760
                                        recurse((char*)NULL, fullname, 2, 1);
 
761
                                }
 
762
                                break;
 
763
                                        /*
 
764
                                         * within "Documents and Settings"
 
765
                                         * or "Users"
 
766
                                         */
 
767
                        case 1 :
 
768
                                accname = (char*)malloc(strlen(name) + 1);
 
769
                                if (accname) {
 
770
                                        strcpy(accname, name);
 
771
                                        if (context->levels > 0)
 
772
                                                recurse(name, fullname,
 
773
                                                        context->levels - 1, 0);
 
774
                                }
 
775
                                break;
 
776
                                        /*
 
777
                                         * not related to "Documents and Settings"
 
778
                                         * or "Users"
 
779
                                         */
 
780
                        case 0 :
 
781
                                account(context->accname, context->dir,
 
782
                                        name, 1);
 
783
                                if (context->levels > 0)
 
784
                                        recurse(context->accname, fullname,
 
785
                                                context->levels - 1, 0);
 
786
                                break;
 
787
                        }
 
788
                }
 
789
                free(fullname);
 
790
        }
 
791
/* check expected return value */
 
792
        return (0);
 
793
}
 
794
 
 
795
STATIC boolean recurse(const char *accname, const char *dir, int levels, int docset)
 
796
{
 
797
        struct CALLBACK context;
 
798
        boolean err;
 
799
 
 
800
        err = DENIED;
 
801
        context.dir = dir;
 
802
        context.accname = accname;
 
803
        context.levels = levels;
 
804
        context.docset = docset;
 
805
        ntfs_read_directory(ntfs_context,dir,callback,&context);
 
806
        return (!err);
 
807
}
 
808
#endif
 
809
 
 
810
/*
 
811
 *          Search directory "Documents and Settings" for user accounts
 
812
 */
 
813
 
 
814
#ifdef WIN32
 
815
 
 
816
STATIC boolean getusers(const char *dir, int levels)
 
817
{
 
818
        WIN32_FIND_DATA found;
 
819
        HANDLE search;
 
820
        char *filter;
 
821
        char *fullname;
 
822
        char *accname;
 
823
        boolean err;
 
824
        const char *docset;
 
825
 
 
826
        /* first get files from "Documents and Settings" */
 
827
        err = DENIED;
 
828
        if (sizeof(OWNERS1) > sizeof(OWNERS2))
 
829
                filter = (char *)malloc(strlen(dir) + strlen(OWNERS1) + 6);
 
830
        else
 
831
                filter = (char *)malloc(strlen(dir) + strlen(OWNERS2) + 6);
 
832
        if (filter) {
 
833
                docset = OWNERS1;
 
834
                strcpy(filter, dir);
 
835
                strcat(filter, "\\");
 
836
                strcat(filter, docset);
 
837
                strcat(filter, "\\*.*");
 
838
                search = FindFirstFile(filter, &found);
 
839
                        /* if failed, retry with "Users" */
 
840
                if (search == INVALID_HANDLE_VALUE) {
 
841
                        docset = OWNERS2;
 
842
                        strcpy(filter, dir);
 
843
                        strcat(filter, "\\");
 
844
                        strcat(filter, docset);
 
845
                        strcat(filter, "\\*.*");
 
846
                        search = FindFirstFile(filter, &found);
 
847
                }
 
848
                if (search != INVALID_HANDLE_VALUE) {
 
849
                        do {
 
850
                                if (found.cFileName[0] != '.') {
 
851
                                        fullname =
 
852
                                            (char *)malloc(strlen(dir)
 
853
                                                         + strlen(docset)
 
854
                                                         + strlen(found.cFileName) + 3);
 
855
                                        accname = (char *)
 
856
                                               malloc(strlen(found.cFileName) + 1);
 
857
                                        if (fullname && accname) {
 
858
                                                strcpy(accname,
 
859
                                                       found.cFileName);
 
860
                                                
 
861
                                                strcpy(fullname, dir);
 
862
                                                strcat(fullname, "\\");
 
863
                                                strcat(fullname, docset);
 
864
                                                strcat(fullname, "\\");
 
865
                                                strcat(fullname,
 
866
                                                       found.cFileName);
 
867
                                                recurse(accname, fullname, 2);
 
868
 
 
869
                                                free(fullname);
 
870
                                        }
 
871
                                }
 
872
                        } while (FindNextFile(search, &found));
 
873
                        FindClose(search);
 
874
                } else {
 
875
                        printf("No subdirectory found in %s\\%s\n",dir,docset);
 
876
                }
 
877
                        /* now search in other directories */
 
878
                strcpy(filter, dir);
 
879
                strcat(filter, "\\*.*");
 
880
                search = FindFirstFile(filter, &found);
 
881
                if (search != INVALID_HANDLE_VALUE) {
 
882
                        do {
 
883
                                if ((found.cFileName[0] != '.')
 
884
                                        && strcmp(found.cFileName,OWNERS1)
 
885
                                        && strcmp(found.cFileName,OWNERS2)) {
 
886
                                        fullname =
 
887
                                            (char *)malloc(strlen(dir)
 
888
                                                         + strlen(found.cFileName) + 2);
 
889
                                        if (fullname) {
 
890
                                                strcpy(fullname, dir);
 
891
                                                strcat(fullname, "\\");
 
892
                                                strcat(fullname,
 
893
                                                       found.cFileName);
 
894
                                                recurse((char*)NULL, fullname, 2);
 
895
                                                free(fullname);
 
896
                                        }
 
897
                                }
 
898
                        } while (FindNextFile(search, &found));
 
899
                        FindClose(search);
 
900
                } else {
 
901
                        printf("No directory found in %s\n",dir);
 
902
                        err = AGREED;
 
903
                }
 
904
        }
 
905
        return (!err);
 
906
}
 
907
 
 
908
#else
 
909
 
 
910
STATIC boolean getusers(const char *dir, int levels)
 
911
{
 
912
        boolean err;
 
913
        struct CALLBACK context;
 
914
 
 
915
        printf("* Search for \"" OWNERS1 "\" and \"" OWNERS2 "\"\n");
 
916
        err = DENIED;
 
917
        context.dir = dir;
 
918
        context.accname = (const char*)NULL;
 
919
        context.levels = levels;
 
920
        context.docset = 2;
 
921
        ntfs_read_directory(ntfs_context,dir,callback,&context);
 
922
        printf("* Search for other directories %s\n",dir);
 
923
        context.docset = 0;
 
924
        ntfs_read_directory(ntfs_context,dir,callback,&context);
 
925
 
 
926
        return (!err);
 
927
}
 
928
 
 
929
#endif
 
930
 
 
931
#ifdef WIN32
 
932
/*
 
933
 *              Get the current login name (Win32 only)
 
934
 */
 
935
 
 
936
STATIC void loginname(boolean silent)
 
937
{
 
938
        char *winname;
 
939
        char *domain;
 
940
        unsigned char *sid;
 
941
        unsigned long namesz;
 
942
        unsigned long sidsz;
 
943
        unsigned long domainsz;
 
944
        int nametype;
 
945
        boolean ok;
 
946
        int r;
 
947
 
 
948
        ok = FALSE;
 
949
        winname = (char*)malloc(MAXNAMESZ);
 
950
        domain = (char*)malloc(MAXNAMESZ);
 
951
        sid = (char*)malloc(MAXSIDSZ);
 
952
 
 
953
        namesz = MAXNAMESZ;
 
954
        domainsz = MAXNAMESZ;
 
955
        sidsz = MAXSIDSZ;
 
956
        if (winname
 
957
            && domain
 
958
            && sid
 
959
            && GetUserName(winname,&namesz)) {
 
960
                winname[namesz] = '\0';
 
961
                if (!silent)
 
962
                        printf("Your current user name is %s\n",winname);
 
963
                nametype = 1;
 
964
                r = LookupAccountName((char*)NULL,winname,sid,&sidsz,
 
965
                        domain,&domainsz,&nametype);
 
966
                if (r) {
 
967
                        domain[domainsz] = '\0';
 
968
                        if (!silent)
 
969
                                printf("Your account domain is %s\n",domain);
 
970
                        ok = AGREED;
 
971
                }
 
972
           }
 
973
        if (ok) {
 
974
                currentwinname = winname;
 
975
                currentdomain = domain;
 
976
                currentsid = sid;
 
977
        } else {
 
978
                currentwinname = (char*)NULL;
 
979
                currentdomain = (char*)NULL;
 
980
                currentsid = (unsigned char*)NULL;
 
981
        }
 
982
}
 
983
 
 
984
/*
 
985
 *              Minimal output on stdout
 
986
 */
 
987
 
 
988
boolean minimal(unsigned char *sid)
 
989
{
 
990
        const unsigned char *groupsid;
 
991
        boolean ok;
 
992
 
 
993
        ok = DENIED;
 
994
        if (sid) {
 
995
                groupsid = makegroupsid(sid);
 
996
                printf("# %s\n",BANNER);
 
997
                printf("# For Windows account \"%s\" in domain \"%s\"\n",
 
998
                        currentwinname, currentdomain);
 
999
                printf("# Replace \"user\" and \"group\" hereafter by matching Linux login\n");
 
1000
                printf("user::%s\n",decodesid(sid));
 
1001
                printf(":group:%s\n",decodesid(groupsid));
 
1002
                ok = AGREED;
 
1003
        }
 
1004
        return (ok);
 
1005
}
 
1006
 
 
1007
#endif
 
1008
 
 
1009
STATIC boolean outputmap(const char *volume, const char *dir)
 
1010
{
 
1011
        char buf[256];
 
1012
        int fn;
 
1013
        char *fullname;
 
1014
        char *backup;
 
1015
        struct MAPPING *mapping;
 
1016
        boolean done;
 
1017
        boolean err;
 
1018
        boolean undecided;
 
1019
#ifdef WIN32
 
1020
#else
 
1021
        struct stat st;
 
1022
        int s;
 
1023
#endif
 
1024
 
 
1025
        done = DENIED;
 
1026
        fullname = (char *)malloc(strlen(MAPFILE) + 1
 
1027
                                + strlen(volume) + 1
 
1028
                                + (dir ? strlen(dir) + 1 : 0));
 
1029
        if (fullname) {
 
1030
#ifdef WIN32
 
1031
                strcpy(fullname, volume);
 
1032
                if (dir && dir[0]) {
 
1033
                        strcat(fullname, "\\");
 
1034
                        strcat(fullname,dir);
 
1035
                }
 
1036
 
 
1037
                        /* build directory, if not present */
 
1038
                if (GetFileAttributes(fullname) & 0x80000000) {
 
1039
                        printf("* Creating directory %s\n", fullname);
 
1040
                        mkdir(fullname);
 
1041
                }
 
1042
 
 
1043
                strcat(fullname, "\\");
 
1044
                strcat(fullname, MAPFILE);
 
1045
                printf("\n");
 
1046
 
 
1047
                if (!(GetFileAttributes(fullname) & 0x80000000)) {
 
1048
                        backup = (char*)malloc(strlen(fullname) + 5);
 
1049
                        strcpy(backup,fullname);
 
1050
                        strcat(backup,".bak");
 
1051
                        unlink(backup);
 
1052
                        if (!rename(fullname,backup))
 
1053
                                printf("* Old mapping file moved to %s\n",backup);
 
1054
                }
 
1055
#else
 
1056
                strcpy(fullname, MAPFILE);
 
1057
                printf("\n");
 
1058
 
 
1059
                s = stat(fullname,&st);
 
1060
                if (!s) {
 
1061
                        backup = (char*)malloc(strlen(fullname + 5));
 
1062
                        strcpy(backup,fullname);
 
1063
                        strcat(backup,".bak");
 
1064
                        if (rename(fullname,backup))
 
1065
                                printf("* Old mapping file moved to %s\n",backup);
 
1066
                }
 
1067
#endif
 
1068
 
 
1069
                printf("* Creating file %s\n", fullname);
 
1070
                err = DENIED;
 
1071
#ifdef WIN32
 
1072
                fn = open(fullname,O_CREAT + O_TRUNC + O_WRONLY + O_BINARY, 
 
1073
                        S_IREAD + S_IWRITE);
 
1074
#else
 
1075
                fn = open(fullname,O_CREAT + O_TRUNC + O_WRONLY,
 
1076
                        S_IREAD + S_IWRITE);
 
1077
#endif
 
1078
                if (fn > 0) {
 
1079
                        sprintf(buf,"# %s\n",BANNER);
 
1080
                        if (!write(fn,buf,strlen(buf)))
 
1081
                                err = AGREED;
 
1082
                        printf("%s",buf);
 
1083
                        undecided = DENIED;
 
1084
                                /* records for owner only or group only */
 
1085
                        for (mapping = firstmapping; mapping && !err;
 
1086
                             mapping = mapping->next)
 
1087
                                if (mapping->defined
 
1088
                                    && (!mapping->uidstr[0] || !mapping->gidstr[0])) {
 
1089
                                        sprintf(buf,"%s:%s:%s\n",
 
1090
                                                mapping->uidstr,
 
1091
                                                mapping->gidstr,
 
1092
                                                mapping->sidstr);
 
1093
                                        if (!write(fn,buf,strlen(buf)))
 
1094
                                                err = AGREED;
 
1095
                                        printf("%s",buf);
 
1096
                                } else
 
1097
                                        undecided = AGREED;
 
1098
                                /* records for both owner and group */
 
1099
                        for (mapping = firstmapping; mapping && !err;
 
1100
                             mapping = mapping->next)
 
1101
                                if (mapping->defined
 
1102
                                    && mapping->uidstr[0] && mapping->gidstr[0]) {
 
1103
                                        sprintf(buf,"%s:%s:%s\n",
 
1104
                                                mapping->uidstr,
 
1105
                                                mapping->gidstr,
 
1106
                                                mapping->sidstr);
 
1107
                                        if (!write(fn,buf,strlen(buf)))
 
1108
                                                err = AGREED;
 
1109
                                        printf("%s",buf);
 
1110
                                } else
 
1111
                                        undecided = AGREED;
 
1112
                        done = !err;
 
1113
                        close(fn);
 
1114
                        if (undecided) {
 
1115
                                printf("Undecided :\n");
 
1116
                                for (mapping = firstmapping; mapping;
 
1117
                                     mapping = mapping->next)
 
1118
                                        if (!mapping->defined) {
 
1119
                                                printf("   %s\n", mapping->sidstr);
 
1120
                                        }
 
1121
                        }
 
1122
#ifndef WIN32
 
1123
                        printf("\n* You will have to move the file \"" MAPFILE "\"\n");
 
1124
                        printf("  to directory \"" MAPDIR "\" after mounting\n");
 
1125
#endif
 
1126
                }
 
1127
        }
 
1128
        if (!done)
 
1129
                fprintf(stderr, "* Could not create mapping file \"%s\"\n", fullname);
 
1130
        return (done);
 
1131
}
 
1132
 
 
1133
STATIC boolean sanitize(void)
 
1134
{
 
1135
        char buf[81];
 
1136
        boolean ok;
 
1137
        int ownercnt;
 
1138
        int groupcnt;
 
1139
        struct MAPPING *mapping;
 
1140
        struct MAPPING *firstowner;
 
1141
        struct MAPPING *genericgroup;
 
1142
        struct MAPPING *group;
 
1143
        char *sidstr;
 
1144
 
 
1145
                /* count owners and groups */
 
1146
                /* and find first user, and a generic group */
 
1147
        ownercnt = 0;
 
1148
        groupcnt = 0;
 
1149
        firstowner = (struct MAPPING*)NULL;
 
1150
        genericgroup = (struct MAPPING*)NULL;
 
1151
        for (mapping=firstmapping; mapping; mapping=mapping->next) {
 
1152
                if (mapping->defined && mapping->uidstr[0]) {
 
1153
                        if (!ownercnt)
 
1154
                                firstowner = mapping;
 
1155
                        ownercnt++;
 
1156
                }
 
1157
                if (mapping->defined && mapping->gidstr[0] && !mapping->uidstr[0]) {
 
1158
                        groupcnt++;
 
1159
                }
 
1160
                if (!mapping->defined && isgenericgroup(mapping->sidstr)) {
 
1161
                        genericgroup = mapping;
 
1162
                }
 
1163
        }
 
1164
#ifdef WIN32
 
1165
                /* no user defined, on Windows, suggest a mapping */
 
1166
                /* based on account currently used */
 
1167
        if (!ownercnt && currentwinname && currentsid) {
 
1168
                char *owner;
 
1169
                char *p;
 
1170
 
 
1171
                printf("\nYou have defined no file owner,\n");
 
1172
                printf("   please enter the Linux login which should be mapped\n");
 
1173
                printf("   to account you are currently using\n");
 
1174
                printf("   Linux user ? ");
 
1175
                p = fgets(buf, 80, stdin);
 
1176
                if (p && p[0] && (p[strlen(p) - 1] == '\n'))
 
1177
                        p[strlen(p) - 1] = '\0';
 
1178
                if (p && p[0]) {
 
1179
                        firstowner = (struct MAPPING*)malloc(sizeof(struct MAPPING));
 
1180
                        owner = (char*)malloc(strlen(p) + 1);
 
1181
                        if (firstowner && owner) {
 
1182
                                strcpy(owner, p);
 
1183
                                firstowner->next = firstmapping;
 
1184
                                firstowner->uidstr = owner;
 
1185
                                firstowner->gidstr = "";
 
1186
                                firstowner->sidstr = decodesid(currentsid);
 
1187
                                firstowner->sid = currentsid;
 
1188
                                firstmapping = firstowner;
 
1189
                                ownercnt++;
 
1190
                                /* prefer a generic group with the same authorities */
 
1191
                                for (mapping=firstmapping; mapping;
 
1192
                                                mapping=mapping->next)
 
1193
                                        if (!mapping->defined
 
1194
                                            && isgenericgroup(mapping->sidstr)
 
1195
                                            && !memcmp(firstowner->sidstr,
 
1196
                                                        mapping->sidstr,
 
1197
                                                        strlen(mapping->sidstr)-3))
 
1198
                                                genericgroup = mapping;
 
1199
                        }
 
1200
                }
 
1201
        }
 
1202
#endif
 
1203
        if (ownercnt) {
 
1204
                        /*
 
1205
                         *   No group was selected, but there were a generic group
 
1206
                         *   insist in using it, associated to the first user
 
1207
                         */
 
1208
                if (!groupcnt) {
 
1209
                        printf("\nYou have defined no group, this can cause problems\n");
 
1210
                        printf("Do you accept defining a standard group ?\n");
 
1211
                        if (!fgets(buf,80,stdin)
 
1212
                           || ((buf[0] != 'n')
 
1213
                              && (buf[0] != 'N'))) {
 
1214
                                if (genericgroup) {
 
1215
                                        genericgroup->uidstr = "";
 
1216
                                        genericgroup->gidstr = firstowner->uidstr;
 
1217
                                        genericgroup->defined = AGREED;
 
1218
                                } else {
 
1219
                                        group = (struct MAPPING*)
 
1220
                                                malloc(sizeof(struct MAPPING));
 
1221
                                        sidstr = decodesid(
 
1222
                                                makegroupsid(firstowner->sid));
 
1223
                                        if (group && sidstr) {
 
1224
                                                group->uidstr = "";
 
1225
                                                group->gidstr = firstowner->
 
1226
                                                                uidstr;
 
1227
                                                group->sidstr = sidstr;
 
1228
                                                group->defined = AGREED;
 
1229
                                                group->next = firstmapping;
 
1230
                                                firstmapping = group;
 
1231
                                        }
 
1232
                                }
 
1233
                        }
 
1234
                }
 
1235
                ok = AGREED;
 
1236
        } else {
 
1237
                printf("\nYou have defined no user, no mapping can be built\n");
 
1238
                ok = DENIED;
 
1239
        }
 
1240
 
 
1241
        return (ok);
 
1242
}
 
1243
 
 
1244
STATIC boolean checkoptions(int argc, char *argv[], boolean silent)
 
1245
{
 
1246
        boolean err;
 
1247
#ifdef WIN32
 
1248
        int xarg;
 
1249
        const char *pvol;
 
1250
 
 
1251
        if (silent)
 
1252
                err = (argc != 1);
 
1253
        else {
 
1254
                err = (argc < 2);
 
1255
                for (xarg=1; (xarg<argc) && !err; xarg++) {
 
1256
                        pvol = argv[xarg];
 
1257
                        if (pvol[0] && (pvol[1] == ':') && !pvol[2]) {
 
1258
                                err = !(((pvol[0] >= 'A') && (pvol[0] <= 'Z'))
 
1259
                                        || ((pvol[0] >= 'a') && (pvol[0] <= 'z')));
 
1260
                        }
 
1261
                }
 
1262
        }
 
1263
        if (err) {
 
1264
                fprintf(stderr, "Usage : usermap [vol1: [vol2: ...]]\n");
 
1265
                fprintf(stderr, "    \"voln\" are the letters of the partition to share with Linux\n");
 
1266
                fprintf(stderr, "        eg C:\n");
 
1267
                fprintf(stderr, "    the Windows system partition should be named first\n");
 
1268
        }
 
1269
#else
 
1270
        unused((void*)argv);
 
1271
        unused((void*)&silent);
 
1272
        err = (argc < 2);
 
1273
        if (err) {
 
1274
                fprintf(stderr, "Usage : usermap dev1 [dev2 ...]\n");
 
1275
                fprintf(stderr, "    \"dev.\" are the devices to share with Windows\n");
 
1276
                fprintf(stderr, "        eg /dev/sdb1\n");
 
1277
                fprintf(stderr, "    the devices should not be mounted\n");
 
1278
                fprintf(stderr, "    the Windows system partition should be named first\n");
 
1279
        } else
 
1280
                if (getuid()) {
 
1281
                        fprintf(stderr, "\nSorry, only root can start usermap\n");
 
1282
                        err = AGREED;
 
1283
                }
 
1284
#endif
 
1285
        return (!err);
 
1286
}
 
1287
 
 
1288
STATIC boolean process(int argc, char *argv[])
 
1289
{
 
1290
        boolean ok;
 
1291
        int xarg;
 
1292
        int targ;
 
1293
 
 
1294
        firstmapping = (struct MAPPING *)NULL;
 
1295
        lastmapping = (struct MAPPING *)NULL;
 
1296
        ok = AGREED;
 
1297
#ifdef WIN32
 
1298
        for (xarg=1; (xarg<argc) && ok; xarg++) {
 
1299
                printf("\n* Scanning \"%s\" (two levels)\n",argv[xarg]);
 
1300
                ok = getusers(argv[xarg],2);
 
1301
        }
 
1302
#else
 
1303
        for (xarg=1; (xarg<argc) && ok; xarg++)
 
1304
                if (open_volume(argv[xarg])) {
 
1305
                        printf("\n* Scanning \"%s\" (two levels)\n",argv[xarg]);
 
1306
                        ok = getusers("/",2);
 
1307
                        close_volume(argv[xarg]);
 
1308
                } else
 
1309
                        ok = DENIED;
 
1310
#endif
 
1311
        if (ok && sanitize()) {
 
1312
                targ = (argc > 2 ? 2 : 1);
 
1313
                if (!outputmap(argv[targ],MAPDIR)) {
 
1314
                        printf("Trying to write file on root directory\n");
 
1315
                        if (outputmap(argv[targ],(const char*)NULL)) {
 
1316
                                printf("\nNote : you will have to move the file to directory \"%s\" on Linux\n",
 
1317
                                        MAPDIR);
 
1318
                        } else
 
1319
                                ok = DENIED;
 
1320
                } else
 
1321
                        ok = DENIED;
 
1322
        } else
 
1323
                ok = DENIED;
 
1324
        return (ok);
 
1325
}
 
1326
 
 
1327
int main(int argc, char *argv[])
 
1328
{
 
1329
        boolean ok;
 
1330
        boolean silent;
 
1331
 
 
1332
        silent = !isatty(1);
 
1333
        if (!silent)
 
1334
                welcome();
 
1335
        if (checkoptions(argc, argv, silent)) {
 
1336
#ifdef WIN32
 
1337
                loginname(silent);
 
1338
                if (silent)
 
1339
                        ok = minimal(currentsid);
 
1340
                else
 
1341
                        ok = process(argc, argv);
 
1342
#else
 
1343
                if (open_security_api()) {
 
1344
                        ok = process(argc,argv);
 
1345
                        if (!close_security_api()) ok = DENIED;
 
1346
                }
 
1347
#endif
 
1348
        } else
 
1349
                ok = DENIED;
 
1350
        if (!ok)
 
1351
                exit(1);
 
1352
        return (0);
 
1353
}