rugged 1.2.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +1 -1
- data/vendor/libgit2/cmake/FindLibSSH2.cmake +13 -0
- data/vendor/libgit2/include/git2/attr.h +7 -1
- data/vendor/libgit2/include/git2/blob.h +7 -1
- data/vendor/libgit2/include/git2/clone.h +1 -1
- data/vendor/libgit2/include/git2/common.h +29 -1
- data/vendor/libgit2/include/git2/deprecated.h +120 -0
- data/vendor/libgit2/include/git2/diff.h +3 -97
- data/vendor/libgit2/include/git2/email.h +127 -0
- data/vendor/libgit2/include/git2/errors.h +1 -0
- data/vendor/libgit2/include/git2/filter.h +7 -1
- data/vendor/libgit2/include/git2/notes.h +2 -2
- data/vendor/libgit2/include/git2/oidarray.h +5 -8
- data/vendor/libgit2/include/git2/remote.h +4 -4
- data/vendor/libgit2/include/git2/repository.h +12 -10
- data/vendor/libgit2/include/git2/stash.h +1 -1
- data/vendor/libgit2/include/git2/stdint.h +3 -3
- data/vendor/libgit2/include/git2/sys/email.h +45 -0
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/src/CMakeLists.txt +7 -0
- data/vendor/libgit2/src/attr.c +24 -9
- data/vendor/libgit2/src/attr_file.c +23 -15
- data/vendor/libgit2/src/attr_file.h +3 -3
- data/vendor/libgit2/src/blame.c +4 -4
- data/vendor/libgit2/src/blame_git.c +1 -1
- data/vendor/libgit2/src/blob.c +15 -9
- data/vendor/libgit2/src/buffer.c +16 -8
- data/vendor/libgit2/src/buffer.h +2 -1
- data/vendor/libgit2/src/cc-compat.h +1 -7
- data/vendor/libgit2/src/checkout.c +6 -7
- data/vendor/libgit2/src/clone.c +1 -1
- data/vendor/libgit2/src/commit_graph.c +1 -1
- data/vendor/libgit2/src/config.c +11 -7
- data/vendor/libgit2/src/config_file.c +2 -2
- data/vendor/libgit2/src/config_parse.c +1 -1
- data/vendor/libgit2/src/describe.c +1 -1
- data/vendor/libgit2/src/diff.c +41 -173
- data/vendor/libgit2/src/email.c +299 -0
- data/vendor/libgit2/src/email.h +25 -0
- data/vendor/libgit2/src/filter.c +7 -1
- data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +8 -8
- data/vendor/libgit2/src/ignore.c +2 -2
- data/vendor/libgit2/src/indexer.c +37 -3
- data/vendor/libgit2/src/libgit2.c +31 -0
- data/vendor/libgit2/src/merge.c +7 -4
- data/vendor/libgit2/src/notes.c +31 -31
- data/vendor/libgit2/src/oidarray.c +10 -1
- data/vendor/libgit2/src/path.c +214 -55
- data/vendor/libgit2/src/path.h +29 -9
- data/vendor/libgit2/src/pathspec.c +1 -1
- data/vendor/libgit2/src/refdb_fs.c +1 -1
- data/vendor/libgit2/src/refs.c +2 -2
- data/vendor/libgit2/src/refspec.c +1 -1
- data/vendor/libgit2/src/remote.c +12 -5
- data/vendor/libgit2/src/repository.c +233 -41
- data/vendor/libgit2/src/repository.h +5 -0
- data/vendor/libgit2/src/reset.c +1 -1
- data/vendor/libgit2/src/revparse.c +4 -4
- data/vendor/libgit2/src/stash.c +1 -1
- data/vendor/libgit2/src/streams/openssl_legacy.c +1 -1
- data/vendor/libgit2/src/streams/openssl_legacy.h +1 -1
- data/vendor/libgit2/src/threadstate.c +2 -1
- data/vendor/libgit2/src/trailer.c +1 -1
- data/vendor/libgit2/src/transports/ssh.c +4 -4
- data/vendor/libgit2/src/transports/winhttp.c +1 -1
- data/vendor/libgit2/src/util.c +1 -1
- data/vendor/libgit2/src/util.h +1 -1
- data/vendor/libgit2/src/win32/findfile.c +1 -1
- data/vendor/libgit2/src/win32/posix.h +6 -6
- data/vendor/libgit2/src/win32/posix_w32.c +9 -6
- metadata +11 -6
@@ -601,9 +601,10 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
|
|
601
601
|
idx->inbuf_len += size - to_expell;
|
602
602
|
}
|
603
603
|
|
604
|
+
#if defined(NO_MMAP) || !defined(GIT_WIN32)
|
605
|
+
|
604
606
|
static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size)
|
605
607
|
{
|
606
|
-
#ifdef NO_MMAP
|
607
608
|
size_t remaining_size = size;
|
608
609
|
const char *ptr = (const char *)data;
|
609
610
|
|
@@ -619,7 +620,31 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
|
|
619
620
|
offset += nb;
|
620
621
|
remaining_size -= nb;
|
621
622
|
}
|
623
|
+
|
624
|
+
return 0;
|
625
|
+
}
|
626
|
+
|
627
|
+
static int append_to_pack(git_indexer *idx, const void *data, size_t size)
|
628
|
+
{
|
629
|
+
if (write_at(idx, data, idx->pack->mwf.size, size) < 0) {
|
630
|
+
git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
|
631
|
+
return -1;
|
632
|
+
}
|
633
|
+
|
634
|
+
return 0;
|
635
|
+
}
|
636
|
+
|
622
637
|
#else
|
638
|
+
|
639
|
+
/*
|
640
|
+
* Windows may keep different views to a networked file for the mmap- and
|
641
|
+
* open-accessed versions of a file, so any writes done through
|
642
|
+
* `write(2)`/`pwrite(2)` may not be reflected on the data that `mmap(2)` is
|
643
|
+
* able to read.
|
644
|
+
*/
|
645
|
+
|
646
|
+
static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size)
|
647
|
+
{
|
623
648
|
git_file fd = idx->pack->mwf.fd;
|
624
649
|
size_t mmap_alignment;
|
625
650
|
size_t page_offset;
|
@@ -644,7 +669,6 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
|
|
644
669
|
map_data = (unsigned char *)map.data;
|
645
670
|
memcpy(map_data + page_offset, data, size);
|
646
671
|
p_munmap(&map);
|
647
|
-
#endif
|
648
672
|
|
649
673
|
return 0;
|
650
674
|
}
|
@@ -680,6 +704,8 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
|
|
680
704
|
return write_at(idx, data, idx->pack->mwf.size, size);
|
681
705
|
}
|
682
706
|
|
707
|
+
#endif
|
708
|
+
|
683
709
|
static int read_stream_object(git_indexer *idx, git_indexer_progress *stats)
|
684
710
|
{
|
685
711
|
git_packfile_stream *stream = &idx->stream;
|
@@ -1279,11 +1305,19 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
|
|
1279
1305
|
if (git_mwindow_free_all(&idx->pack->mwf) < 0)
|
1280
1306
|
goto on_error;
|
1281
1307
|
|
1282
|
-
|
1308
|
+
#if !defined(NO_MMAP) && defined(GIT_WIN32)
|
1309
|
+
/*
|
1310
|
+
* Some non-Windows remote filesystems fail when truncating files if the
|
1311
|
+
* file permissions change after opening the file (done by p_mkstemp).
|
1312
|
+
*
|
1313
|
+
* Truncation is only needed when mmap is used to undo rounding up to next
|
1314
|
+
* page_size in append_to_pack.
|
1315
|
+
*/
|
1283
1316
|
if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) {
|
1284
1317
|
git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name);
|
1285
1318
|
return -1;
|
1286
1319
|
}
|
1320
|
+
#endif
|
1287
1321
|
|
1288
1322
|
if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) {
|
1289
1323
|
git_error_set(GIT_ERROR_OS, "failed to fsync packfile");
|
@@ -52,6 +52,7 @@ static void libgit2_settings_global_shutdown(void)
|
|
52
52
|
{
|
53
53
|
git__free(git__user_agent);
|
54
54
|
git__free(git__ssl_ciphers);
|
55
|
+
git_repository__free_extensions();
|
55
56
|
}
|
56
57
|
|
57
58
|
static int git_libgit2_settings_global_init(void)
|
@@ -367,6 +368,36 @@ int git_libgit2_opts(int key, ...)
|
|
367
368
|
git_odb__loose_priority = va_arg(ap, int);
|
368
369
|
break;
|
369
370
|
|
371
|
+
case GIT_OPT_SET_EXTENSIONS:
|
372
|
+
{
|
373
|
+
const char **extensions = va_arg(ap, const char **);
|
374
|
+
size_t len = va_arg(ap, size_t);
|
375
|
+
error = git_repository__set_extensions(extensions, len);
|
376
|
+
}
|
377
|
+
break;
|
378
|
+
|
379
|
+
case GIT_OPT_GET_EXTENSIONS:
|
380
|
+
{
|
381
|
+
git_strarray *out = va_arg(ap, git_strarray *);
|
382
|
+
char **extensions;
|
383
|
+
size_t len;
|
384
|
+
|
385
|
+
if ((error = git_repository__extensions(&extensions, &len)) < 0)
|
386
|
+
break;
|
387
|
+
|
388
|
+
out->strings = extensions;
|
389
|
+
out->count = len;
|
390
|
+
}
|
391
|
+
break;
|
392
|
+
|
393
|
+
case GIT_OPT_GET_OWNER_VALIDATION:
|
394
|
+
*(va_arg(ap, int *)) = git_repository__validate_ownership;
|
395
|
+
break;
|
396
|
+
|
397
|
+
case GIT_OPT_SET_OWNER_VALIDATION:
|
398
|
+
git_repository__validate_ownership = (va_arg(ap, int) != 0);
|
399
|
+
break;
|
400
|
+
|
370
401
|
default:
|
371
402
|
git_error_set(GIT_ERROR_INVALID, "invalid option key");
|
372
403
|
error = -1;
|
data/vendor/libgit2/src/merge.c
CHANGED
@@ -816,8 +816,11 @@ static int merge_conflict_resolve_one_renamed(
|
|
816
816
|
conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
|
817
817
|
return 0;
|
818
818
|
|
819
|
-
ours_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->our_entry.id) != 0)
|
820
|
-
|
819
|
+
ours_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->our_entry.id) != 0) ||
|
820
|
+
(conflict->ancestor_entry.mode != conflict->our_entry.mode);
|
821
|
+
|
822
|
+
theirs_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->their_entry.id) != 0) ||
|
823
|
+
(conflict->ancestor_entry.mode != conflict->their_entry.mode);
|
821
824
|
|
822
825
|
/* if both are modified (and not to a common target) require a merge */
|
823
826
|
if (ours_changed && theirs_changed &&
|
@@ -1151,7 +1154,7 @@ static void deletes_by_oid_free(git_oidmap *map) {
|
|
1151
1154
|
git_oidmap_free(map);
|
1152
1155
|
}
|
1153
1156
|
|
1154
|
-
static int deletes_by_oid_enqueue(git_oidmap *map, git_pool*
|
1157
|
+
static int deletes_by_oid_enqueue(git_oidmap *map, git_pool *pool, const git_oid *id, size_t idx)
|
1155
1158
|
{
|
1156
1159
|
deletes_by_oid_queue *queue;
|
1157
1160
|
size_t *array_entry;
|
@@ -2366,7 +2369,7 @@ done:
|
|
2366
2369
|
|
2367
2370
|
git_annotated_commit_free(other);
|
2368
2371
|
git_annotated_commit_free(new_base);
|
2369
|
-
|
2372
|
+
git_oidarray_dispose(&bases);
|
2370
2373
|
git_array_clear(head_ids);
|
2371
2374
|
return error;
|
2372
2375
|
}
|
data/vendor/libgit2/src/notes.c
CHANGED
@@ -407,31 +407,33 @@ cleanup:
|
|
407
407
|
return error;
|
408
408
|
}
|
409
409
|
|
410
|
-
static int note_get_default_ref(
|
410
|
+
static int note_get_default_ref(git_buf *out, git_repository *repo)
|
411
411
|
{
|
412
412
|
git_config *cfg;
|
413
|
-
int
|
413
|
+
int error;
|
414
|
+
|
415
|
+
if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
|
416
|
+
return error;
|
414
417
|
|
415
|
-
|
416
|
-
cfg, "core.notesref", GIT_NOTES_DEFAULT_REF);
|
418
|
+
error = git_config_get_string_buf(out, cfg, "core.notesref");
|
417
419
|
|
418
|
-
|
420
|
+
if (error == GIT_ENOTFOUND)
|
421
|
+
error = git_buf_puts(out, GIT_NOTES_DEFAULT_REF);
|
422
|
+
|
423
|
+
return error;
|
419
424
|
}
|
420
425
|
|
421
|
-
static int normalize_namespace(
|
426
|
+
static int normalize_namespace(git_buf *out, git_repository *repo, const char *notes_ref)
|
422
427
|
{
|
423
|
-
if (notes_ref)
|
424
|
-
|
425
|
-
GIT_ERROR_CHECK_ALLOC(*out);
|
426
|
-
return 0;
|
427
|
-
}
|
428
|
+
if (notes_ref)
|
429
|
+
return git_buf_puts(out, notes_ref);
|
428
430
|
|
429
431
|
return note_get_default_ref(out, repo);
|
430
432
|
}
|
431
433
|
|
432
434
|
static int retrieve_note_commit(
|
433
435
|
git_commit **commit_out,
|
434
|
-
|
436
|
+
git_buf *notes_ref_out,
|
435
437
|
git_repository *repo,
|
436
438
|
const char *notes_ref)
|
437
439
|
{
|
@@ -441,7 +443,7 @@ static int retrieve_note_commit(
|
|
441
443
|
if ((error = normalize_namespace(notes_ref_out, repo, notes_ref)) < 0)
|
442
444
|
return error;
|
443
445
|
|
444
|
-
if ((error = git_reference_name_to_id(&oid, repo,
|
446
|
+
if ((error = git_reference_name_to_id(&oid, repo, notes_ref_out->ptr)) < 0)
|
445
447
|
return error;
|
446
448
|
|
447
449
|
if (git_commit_lookup(commit_out, repo, &oid) < 0)
|
@@ -476,7 +478,7 @@ int git_note_read(git_note **out, git_repository *repo,
|
|
476
478
|
const char *notes_ref_in, const git_oid *oid)
|
477
479
|
{
|
478
480
|
int error;
|
479
|
-
|
481
|
+
git_buf notes_ref = GIT_BUF_INIT;
|
480
482
|
git_commit *commit = NULL;
|
481
483
|
|
482
484
|
error = retrieve_note_commit(&commit, ¬es_ref, repo, notes_ref_in);
|
@@ -487,7 +489,7 @@ int git_note_read(git_note **out, git_repository *repo,
|
|
487
489
|
error = git_note_commit_read(out, repo, commit, oid);
|
488
490
|
|
489
491
|
cleanup:
|
490
|
-
|
492
|
+
git_buf_dispose(¬es_ref);
|
491
493
|
git_commit_free(commit);
|
492
494
|
return error;
|
493
495
|
}
|
@@ -534,7 +536,7 @@ int git_note_create(
|
|
534
536
|
int allow_note_overwrite)
|
535
537
|
{
|
536
538
|
int error;
|
537
|
-
|
539
|
+
git_buf notes_ref = GIT_BUF_INIT;
|
538
540
|
git_commit *existing_notes_commit = NULL;
|
539
541
|
git_reference *ref = NULL;
|
540
542
|
git_oid notes_blob_oid, notes_commit_oid;
|
@@ -553,14 +555,14 @@ int git_note_create(
|
|
553
555
|
if (error < 0)
|
554
556
|
goto cleanup;
|
555
557
|
|
556
|
-
error = git_reference_create(&ref, repo, notes_ref,
|
558
|
+
error = git_reference_create(&ref, repo, notes_ref.ptr,
|
557
559
|
¬es_commit_oid, 1, NULL);
|
558
560
|
|
559
561
|
if (out != NULL)
|
560
562
|
git_oid_cpy(out, ¬es_blob_oid);
|
561
563
|
|
562
564
|
cleanup:
|
563
|
-
|
565
|
+
git_buf_dispose(¬es_ref);
|
564
566
|
git_commit_free(existing_notes_commit);
|
565
567
|
git_reference_free(ref);
|
566
568
|
return error;
|
@@ -596,7 +598,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in,
|
|
596
598
|
const git_oid *oid)
|
597
599
|
{
|
598
600
|
int error;
|
599
|
-
|
601
|
+
git_buf notes_ref_target = GIT_BUF_INIT;
|
600
602
|
git_commit *existing_notes_commit = NULL;
|
601
603
|
git_oid new_notes_commit;
|
602
604
|
git_reference *notes_ref = NULL;
|
@@ -612,11 +614,11 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in,
|
|
612
614
|
if (error < 0)
|
613
615
|
goto cleanup;
|
614
616
|
|
615
|
-
error = git_reference_create(¬es_ref, repo, notes_ref_target,
|
617
|
+
error = git_reference_create(¬es_ref, repo, notes_ref_target.ptr,
|
616
618
|
&new_notes_commit, 1, NULL);
|
617
619
|
|
618
620
|
cleanup:
|
619
|
-
|
621
|
+
git_buf_dispose(¬es_ref_target);
|
620
622
|
git_reference_free(notes_ref);
|
621
623
|
git_commit_free(existing_notes_commit);
|
622
624
|
return error;
|
@@ -624,18 +626,16 @@ cleanup:
|
|
624
626
|
|
625
627
|
int git_note_default_ref(git_buf *out, git_repository *repo)
|
626
628
|
{
|
627
|
-
char *default_ref;
|
628
629
|
int error;
|
629
630
|
|
630
631
|
GIT_ASSERT_ARG(out);
|
631
632
|
GIT_ASSERT_ARG(repo);
|
632
633
|
|
633
634
|
if ((error = git_buf_sanitize(out)) < 0 ||
|
634
|
-
(error = note_get_default_ref(
|
635
|
-
|
635
|
+
(error = note_get_default_ref(out, repo)) < 0)
|
636
|
+
git_buf_dispose(out);
|
636
637
|
|
637
|
-
|
638
|
-
return 0;
|
638
|
+
return error;
|
639
639
|
}
|
640
640
|
|
641
641
|
const git_signature *git_note_committer(const git_note *note)
|
@@ -674,7 +674,7 @@ void git_note_free(git_note *note)
|
|
674
674
|
}
|
675
675
|
|
676
676
|
static int process_entry_path(
|
677
|
-
const char*
|
677
|
+
const char *entry_path,
|
678
678
|
git_oid *annotated_object_id)
|
679
679
|
{
|
680
680
|
int error = 0;
|
@@ -780,7 +780,7 @@ int git_note_iterator_new(
|
|
780
780
|
{
|
781
781
|
int error;
|
782
782
|
git_commit *commit = NULL;
|
783
|
-
|
783
|
+
git_buf notes_ref = GIT_BUF_INIT;
|
784
784
|
|
785
785
|
error = retrieve_note_commit(&commit, ¬es_ref, repo, notes_ref_in);
|
786
786
|
if (error < 0)
|
@@ -789,15 +789,15 @@ int git_note_iterator_new(
|
|
789
789
|
error = git_note_commit_iterator_new(it, commit);
|
790
790
|
|
791
791
|
cleanup:
|
792
|
-
|
792
|
+
git_buf_dispose(¬es_ref);
|
793
793
|
git_commit_free(commit);
|
794
794
|
|
795
795
|
return error;
|
796
796
|
}
|
797
797
|
|
798
798
|
int git_note_next(
|
799
|
-
git_oid*
|
800
|
-
git_oid*
|
799
|
+
git_oid *note_id,
|
800
|
+
git_oid *annotated_id,
|
801
801
|
git_note_iterator *it)
|
802
802
|
{
|
803
803
|
int error;
|
@@ -10,7 +10,7 @@
|
|
10
10
|
#include "git2/oidarray.h"
|
11
11
|
#include "array.h"
|
12
12
|
|
13
|
-
void
|
13
|
+
void git_oidarray_dispose(git_oidarray *arr)
|
14
14
|
{
|
15
15
|
git__free(arr->ids);
|
16
16
|
}
|
@@ -32,3 +32,12 @@ void git_oidarray__reverse(git_oidarray *arr)
|
|
32
32
|
git_oid_cpy(&arr->ids[(arr->count-1)-i], &tmp);
|
33
33
|
}
|
34
34
|
}
|
35
|
+
|
36
|
+
#ifndef GIT_DEPRECATE_HARD
|
37
|
+
|
38
|
+
void git_oidarray_free(git_oidarray *arr)
|
39
|
+
{
|
40
|
+
git_oidarray_dispose(arr);
|
41
|
+
}
|
42
|
+
|
43
|
+
#endif
|
data/vendor/libgit2/src/path.c
CHANGED
@@ -413,7 +413,7 @@ int git_path_to_dir(git_buf *path)
|
|
413
413
|
return git_buf_oom(path) ? -1 : 0;
|
414
414
|
}
|
415
415
|
|
416
|
-
void git_path_string_to_dir(char*
|
416
|
+
void git_path_string_to_dir(char *path, size_t size)
|
417
417
|
{
|
418
418
|
size_t end = strlen(path);
|
419
419
|
|
@@ -2024,78 +2024,237 @@ done:
|
|
2024
2024
|
return supported;
|
2025
2025
|
}
|
2026
2026
|
|
2027
|
-
|
2027
|
+
static git_path__mock_owner_t mock_owner = GIT_PATH_MOCK_OWNER_NONE;
|
2028
|
+
|
2029
|
+
void git_path__set_owner(git_path__mock_owner_t owner)
|
2030
|
+
{
|
2031
|
+
mock_owner = owner;
|
2032
|
+
}
|
2033
|
+
|
2034
|
+
#ifdef GIT_WIN32
|
2035
|
+
static PSID *sid_dup(PSID sid)
|
2036
|
+
{
|
2037
|
+
DWORD len;
|
2038
|
+
PSID dup;
|
2039
|
+
|
2040
|
+
len = GetLengthSid(sid);
|
2041
|
+
|
2042
|
+
if ((dup = git__malloc(len)) == NULL)
|
2043
|
+
return NULL;
|
2044
|
+
|
2045
|
+
if (!CopySid(len, dup, sid)) {
|
2046
|
+
git_error_set(GIT_ERROR_OS, "could not duplicate sid");
|
2047
|
+
git__free(dup);
|
2048
|
+
return NULL;
|
2049
|
+
}
|
2050
|
+
|
2051
|
+
return dup;
|
2052
|
+
}
|
2053
|
+
|
2054
|
+
static int current_user_sid(PSID *out)
|
2028
2055
|
{
|
2029
|
-
#ifndef GIT_WIN32
|
2030
|
-
GIT_UNUSED(path);
|
2031
|
-
return GIT_OK;
|
2032
|
-
#else
|
2033
|
-
git_win32_path buf;
|
2034
|
-
PSID owner_sid;
|
2035
|
-
PSECURITY_DESCRIPTOR descriptor = NULL;
|
2036
|
-
HANDLE token;
|
2037
2056
|
TOKEN_USER *info = NULL;
|
2038
|
-
|
2039
|
-
|
2057
|
+
HANDLE token = NULL;
|
2058
|
+
DWORD len = 0;
|
2059
|
+
int error = -1;
|
2040
2060
|
|
2041
|
-
if (
|
2042
|
-
|
2061
|
+
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
|
2062
|
+
git_error_set(GIT_ERROR_OS, "could not lookup process information");
|
2063
|
+
goto done;
|
2064
|
+
}
|
2065
|
+
|
2066
|
+
if (GetTokenInformation(token, TokenUser, NULL, 0, &len) ||
|
2067
|
+
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
2068
|
+
git_error_set(GIT_ERROR_OS, "could not lookup token metadata");
|
2069
|
+
goto done;
|
2070
|
+
}
|
2043
2071
|
|
2044
|
-
|
2045
|
-
|
2046
|
-
DACL_SECURITY_INFORMATION,
|
2047
|
-
&owner_sid, NULL, NULL, NULL, &descriptor);
|
2072
|
+
info = git__malloc(len);
|
2073
|
+
GIT_ERROR_CHECK_ALLOC(info);
|
2048
2074
|
|
2049
|
-
if (
|
2050
|
-
|
2051
|
-
goto
|
2075
|
+
if (!GetTokenInformation(token, TokenUser, info, len, &len)) {
|
2076
|
+
git_error_set(GIT_ERROR_OS, "could not lookup current user");
|
2077
|
+
goto done;
|
2052
2078
|
}
|
2053
2079
|
|
2054
|
-
if (
|
2080
|
+
if ((*out = sid_dup(info->User.Sid)))
|
2081
|
+
error = 0;
|
2082
|
+
|
2083
|
+
done:
|
2084
|
+
if (token)
|
2085
|
+
CloseHandle(token);
|
2086
|
+
|
2087
|
+
git__free(info);
|
2088
|
+
return error;
|
2089
|
+
}
|
2090
|
+
|
2091
|
+
static int file_owner_sid(PSID *out, const char *path)
|
2092
|
+
{
|
2093
|
+
git_win32_path path_w32;
|
2094
|
+
PSECURITY_DESCRIPTOR descriptor = NULL;
|
2095
|
+
PSID owner_sid;
|
2096
|
+
DWORD ret;
|
2097
|
+
int error = -1;
|
2098
|
+
|
2099
|
+
if (git_win32_path_from_utf8(path_w32, path) < 0)
|
2100
|
+
return -1;
|
2101
|
+
|
2102
|
+
ret = GetNamedSecurityInfoW(path_w32, SE_FILE_OBJECT,
|
2103
|
+
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
2104
|
+
&owner_sid, NULL, NULL, NULL, &descriptor);
|
2105
|
+
|
2106
|
+
if (ret == ERROR_FILE_NOT_FOUND || ret == ERROR_PATH_NOT_FOUND)
|
2107
|
+
error = GIT_ENOTFOUND;
|
2108
|
+
else if (ret != ERROR_SUCCESS)
|
2055
2109
|
git_error_set(GIT_ERROR_OS, "failed to get security information");
|
2056
|
-
|
2057
|
-
|
2110
|
+
else if (!IsValidSid(owner_sid))
|
2111
|
+
git_error_set(GIT_ERROR_OS, "file owner is not valid");
|
2112
|
+
else if ((*out = sid_dup(owner_sid)))
|
2113
|
+
error = 0;
|
2114
|
+
|
2115
|
+
if (descriptor)
|
2116
|
+
LocalFree(descriptor);
|
2117
|
+
|
2118
|
+
return error;
|
2119
|
+
}
|
2120
|
+
|
2121
|
+
int git_path_owner_is_current_user(bool *out, const char *path)
|
2122
|
+
{
|
2123
|
+
PSID owner_sid = NULL, user_sid = NULL;
|
2124
|
+
int error = -1;
|
2125
|
+
|
2126
|
+
if (mock_owner) {
|
2127
|
+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_CURRENT_USER);
|
2128
|
+
return 0;
|
2129
|
+
}
|
2130
|
+
|
2131
|
+
if ((error = file_owner_sid(&owner_sid, path)) < 0 ||
|
2132
|
+
(error = current_user_sid(&user_sid)) < 0)
|
2133
|
+
goto done;
|
2134
|
+
|
2135
|
+
*out = EqualSid(owner_sid, user_sid);
|
2136
|
+
error = 0;
|
2137
|
+
|
2138
|
+
done:
|
2139
|
+
git__free(owner_sid);
|
2140
|
+
git__free(user_sid);
|
2141
|
+
return error;
|
2142
|
+
}
|
2143
|
+
|
2144
|
+
int git_path_owner_is_system(bool *out, const char *path)
|
2145
|
+
{
|
2146
|
+
PSID owner_sid;
|
2147
|
+
|
2148
|
+
if (mock_owner) {
|
2149
|
+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_SYSTEM);
|
2150
|
+
return 0;
|
2058
2151
|
}
|
2059
2152
|
|
2060
|
-
if (
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2153
|
+
if (file_owner_sid(&owner_sid, path) < 0)
|
2154
|
+
return -1;
|
2155
|
+
|
2156
|
+
*out = IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
|
2157
|
+
IsWellKnownSid(owner_sid, WinLocalSystemSid);
|
2158
|
+
|
2159
|
+
git__free(owner_sid);
|
2160
|
+
return 0;
|
2161
|
+
}
|
2162
|
+
|
2163
|
+
int git_path_owner_is_system_or_current_user(bool *out, const char *path)
|
2164
|
+
{
|
2165
|
+
PSID owner_sid = NULL, user_sid = NULL;
|
2166
|
+
int error = -1;
|
2167
|
+
|
2168
|
+
if (mock_owner) {
|
2169
|
+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_SYSTEM ||
|
2170
|
+
mock_owner == GIT_PATH_MOCK_OWNER_CURRENT_USER);
|
2171
|
+
return 0;
|
2064
2172
|
}
|
2065
2173
|
|
2174
|
+
if (file_owner_sid(&owner_sid, path) < 0)
|
2175
|
+
goto done;
|
2176
|
+
|
2066
2177
|
if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
|
2067
2178
|
IsWellKnownSid(owner_sid, WinLocalSystemSid)) {
|
2068
|
-
|
2069
|
-
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2073
|
-
if (
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2179
|
+
*out = 1;
|
2180
|
+
error = 0;
|
2181
|
+
goto done;
|
2182
|
+
}
|
2183
|
+
|
2184
|
+
if (current_user_sid(&user_sid) < 0)
|
2185
|
+
goto done;
|
2186
|
+
|
2187
|
+
*out = EqualSid(owner_sid, user_sid);
|
2188
|
+
error = 0;
|
2189
|
+
|
2190
|
+
done:
|
2191
|
+
git__free(owner_sid);
|
2192
|
+
git__free(user_sid);
|
2193
|
+
return error;
|
2194
|
+
}
|
2195
|
+
|
2196
|
+
#else
|
2197
|
+
|
2198
|
+
static int path_owner_is(bool *out, const char *path, uid_t *uids, size_t uids_len)
|
2199
|
+
{
|
2200
|
+
struct stat st;
|
2201
|
+
size_t i;
|
2202
|
+
|
2203
|
+
*out = false;
|
2204
|
+
|
2205
|
+
if (p_lstat(path, &st) != 0) {
|
2206
|
+
if (errno == ENOENT)
|
2207
|
+
return GIT_ENOTFOUND;
|
2208
|
+
|
2209
|
+
git_error_set(GIT_ERROR_OS, "could not stat '%s'", path);
|
2210
|
+
return -1;
|
2211
|
+
}
|
2212
|
+
|
2213
|
+
for (i = 0; i < uids_len; i++) {
|
2214
|
+
if (uids[i] == st.st_uid) {
|
2215
|
+
*out = true;
|
2216
|
+
break;
|
2080
2217
|
}
|
2081
2218
|
}
|
2082
2219
|
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2220
|
+
return 0;
|
2221
|
+
}
|
2222
|
+
|
2223
|
+
int git_path_owner_is_current_user(bool *out, const char *path)
|
2224
|
+
{
|
2225
|
+
uid_t userid = geteuid();
|
2226
|
+
|
2227
|
+
if (mock_owner) {
|
2228
|
+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_CURRENT_USER);
|
2229
|
+
return 0;
|
2092
2230
|
}
|
2093
|
-
git__free(info);
|
2094
2231
|
|
2095
|
-
|
2096
|
-
|
2097
|
-
LocalFree(descriptor);
|
2232
|
+
return path_owner_is(out, path, &userid, 1);
|
2233
|
+
}
|
2098
2234
|
|
2099
|
-
|
2100
|
-
|
2235
|
+
int git_path_owner_is_system(bool *out, const char *path)
|
2236
|
+
{
|
2237
|
+
uid_t userid = 0;
|
2238
|
+
|
2239
|
+
if (mock_owner) {
|
2240
|
+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_SYSTEM);
|
2241
|
+
return 0;
|
2242
|
+
}
|
2243
|
+
|
2244
|
+
return path_owner_is(out, path, &userid, 1);
|
2245
|
+
}
|
2246
|
+
|
2247
|
+
int git_path_owner_is_system_or_current_user(bool *out, const char *path)
|
2248
|
+
{
|
2249
|
+
uid_t userids[2] = { geteuid(), 0 };
|
2250
|
+
|
2251
|
+
if (mock_owner) {
|
2252
|
+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_SYSTEM ||
|
2253
|
+
mock_owner == GIT_PATH_MOCK_OWNER_CURRENT_USER);
|
2254
|
+
return 0;
|
2255
|
+
}
|
2256
|
+
|
2257
|
+
return path_owner_is(out, path, userids, 2);
|
2101
2258
|
}
|
2259
|
+
|
2260
|
+
#endif
|