Skip to content

Commit fbecce9

Browse files
authored
Windows: enhance user privilege handling and add printsid command (#6651)
1 parent fb80532 commit fbecce9

File tree

13 files changed

+128
-23
lines changed

13 files changed

+128
-23
lines changed

cmd/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"net/http"
2222
_ "net/http/pprof"
2323
"os"
24+
"runtime"
2425
"strconv"
2526
"strings"
2627
"sync"
@@ -88,6 +89,10 @@ func Main(args []string) error {
8889
},
8990
}
9091

92+
if runtime.GOOS == "windows" {
93+
app.Commands = append(app.Commands, cmdPrintSID())
94+
}
95+
9196
if calledViaMount(args) {
9297
var err error
9398
args, err = handleSysMountArgs(args)

cmd/mdtest.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
_ "net/http/pprof"
2323
"os"
2424
"path"
25+
"runtime"
2526
"sync"
2627
"time"
2728

@@ -35,9 +36,17 @@ import (
3536
"github.com/urfave/cli/v2"
3637
)
3738

38-
var ctx = meta.NewContext(1, uint32(os.Getuid()), []uint32{uint32(os.Getgid())})
39+
var ctx = meta.NewContext(1, uint32(utils.GetCurrentUID()), []uint32{uint32(utils.GetCurrentGID())})
3940
var umask = uint16(utils.GetUmask())
4041

42+
func init() {
43+
// For all the juicefs command, we treat admin/elevated privilege user as root(0) on Windows
44+
// just like the mount option '-adminasroot' does for the mounted filesystem.
45+
if runtime.GOOS == "windows" && utils.IsWinAdminOrElevatedPrivilege() {
46+
ctx = meta.NewContext(1, 0, []uint32{0})
47+
}
48+
}
49+
4150
func createDir(jfs *fs.FileSystem, root string, d int, width int) error {
4251
if err := jfs.Mkdir(ctx, root, 0777, umask); err != 0 {
4352
return fmt.Errorf("Mkdir %s: %s", root, err)

cmd/object.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"math/rand"
2626
"os"
2727
"path"
28+
"runtime"
2829
"sort"
2930
"strings"
3031
"sync"
@@ -414,7 +415,11 @@ func (j *juiceFS) Shutdown() {
414415
}
415416

416417
func newJFS(endpoint, accessKey, secretKey, token string) (object.ObjectStorage, error) {
417-
pid, uid, gid = uint32(os.Getpid()), uint32(os.Getuid()), uint32(os.Getgid())
418+
pid, uid, gid = uint32(os.Getpid()), uint32(utils.GetCurrentUID()), uint32(utils.GetCurrentGID())
419+
if runtime.GOOS == "windows" && utils.IsWinAdminOrElevatedPrivilege() {
420+
uid = 0
421+
gid = 0
422+
}
418423
metaUrl := os.Getenv(endpoint)
419424
if metaUrl == "" {
420425
metaUrl = endpoint

cmd/printsid.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
7+
"github.com/juicedata/juicefs/pkg/utils"
8+
"github.com/urfave/cli/v2"
9+
)
10+
11+
func cmdPrintSID() *cli.Command {
12+
return &cli.Command{
13+
Name: "printsid",
14+
Category: "TOOL",
15+
Action: printSID,
16+
Usage: "Show SID info and the convected UID/GID for the current user.",
17+
Hidden: true,
18+
}
19+
}
20+
21+
func printSID(ctx *cli.Context) error {
22+
if runtime.GOOS != "windows" {
23+
return fmt.Errorf("printsid command is only supported on Windows")
24+
}
25+
26+
userSid := utils.GetCurrentUserSIDStr()
27+
groupSid := utils.GetCurrentUserGroupSIDStr()
28+
fmt.Printf("Current User SID: %s, UID: %d\n", userSid, utils.GetCurrentUID())
29+
fmt.Printf("Current Group SID: %s, GID: %d\n", groupSid, utils.GetCurrentGID())
30+
31+
return nil
32+
}

cmd/restore.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ $ juicefs restore redis://localhost/1 2023-05-10-01`,
4343

4444
func restore(ctx *cli.Context) error {
4545
setup0(ctx, 2, 0)
46+
if runtime.GOOS == "windows" && !utils.IsWinAdminOrElevatedPrivilege() {
47+
return fmt.Errorf("restore command requires Administrator or elevated privilege on Windows")
48+
}
4649
if os.Getuid() != 0 && runtime.GOOS != "windows" {
4750
return fmt.Errorf("only root can restore files from trash")
4851
}

cmd/rmr.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"fmt"
2121
"os"
2222
"path/filepath"
23+
"runtime"
2324

2425
"github.com/juicedata/juicefs/pkg/meta"
2526
"github.com/juicedata/juicefs/pkg/utils"
@@ -81,8 +82,10 @@ func rmr(ctx *cli.Context) error {
8182
numThreads = 255
8283
}
8384
if ctx.Bool("skip-trash") {
84-
if os.Getuid() != 0 {
85+
if runtime.GOOS != "windows" && os.Getuid() != 0 {
8586
logger.Fatalf("Only root can remove files directly")
87+
} else if runtime.GOOS == "windows" && !utils.IsWinAdminOrElevatedPrivilege() {
88+
logger.Fatalf("Removing files directly requires Administrator or elevated privilege on Windows")
8689
}
8790
flag = 1
8891
}

pkg/fs/http.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ func (h *indexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
336336
}
337337

338338
func StartHTTPServer(fs *FileSystem, config WebdavConfig) {
339-
ctx := meta.NewContext(uint32(os.Getpid()), uint32(os.Getuid()), []uint32{uint32(os.Getgid())})
339+
ctx := meta.NewContext(uint32(os.Getpid()), uint32(utils.GetCurrentUID()), []uint32{uint32(utils.GetCurrentGID())})
340340
hfs := &webdavFS{ctx, fs, uint16(utils.GetUmask()), config}
341341
srv := &webdav.Handler{
342342
FileSystem: hfs,

pkg/gateway/gateway.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ type Config struct {
7171
}
7272

7373
func NewJFSGateway(jfs *fs.FileSystem, conf *vfs.Config, gConf *Config) (minio.ObjectLayer, error) {
74-
mctx = meta.NewContext(uint32(os.Getpid()), uint32(os.Getuid()), []uint32{uint32(os.Getgid())})
74+
mctx = meta.NewContext(uint32(os.Getpid()), uint32(utils.GetCurrentUID()), []uint32{uint32(utils.GetCurrentGID())})
7575
jfsObj := &jfsObjects{fs: jfs, conf: conf, listPool: minio.NewTreeWalkPool(time.Second * 10), gConf: gConf, nsMutex: minio.NewNSLock(false)}
7676
go jfsObj.cleanup()
7777
return jfsObj, nil

pkg/object/nfs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ func newNFSStore(addr, username, pass, token string) (ObjectStorage, error) {
465465
if err != nil {
466466
return nil, fmt.Errorf("unable to dial MOUNT service %s: %v", addr, err)
467467
}
468-
auth := rpc.NewAuthUnix(username, uint32(os.Getuid()), uint32(os.Getgid()))
468+
auth := rpc.NewAuthUnix(username, uint32(utils.GetCurrentUID()), uint32(utils.GetCurrentGID()))
469469
target, err := mount.Mount(path, auth.Auth())
470470
target.Config.DirCount = 1 << 17
471471
// Readdir returns up to 1M at a time, even if MaxCount is set larger

pkg/utils/utils_unix.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,26 @@ import (
2929
"golang.org/x/sys/unix"
3030
)
3131

32+
func GetCurrentUID() int {
33+
return os.Getuid()
34+
}
35+
36+
func GetCurrentGID() int {
37+
return os.Getgid()
38+
}
39+
40+
func GetCurrentUserSIDStr() string {
41+
return ""
42+
}
43+
44+
func GetCurrentUserGroupSIDStr() string {
45+
return ""
46+
}
47+
48+
func IsWinAdminOrElevatedPrivilege() bool {
49+
return false
50+
}
51+
3252
func GetFileInode(path string) (uint64, error) {
3353
fi, err := os.Stat(path)
3454
if err != nil {

0 commit comments

Comments
 (0)