...

Source file src/os/user/getgrouplist_darwin.go

     1	// Copyright 2016 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build cgo,!osusergo
     6	
     7	package user
     8	
     9	/*
    10	#include <unistd.h>
    11	#include <sys/types.h>
    12	#include <stdlib.h>
    13	
    14	static int mygetgrouplist(const char* user, gid_t group, gid_t* groups, int* ngroups) {
    15		int* buf = malloc(*ngroups * sizeof(int));
    16		int rv = getgrouplist(user, (int) group, buf, ngroups);
    17		int i;
    18		if (rv == 0) {
    19			for (i = 0; i < *ngroups; i++) {
    20				groups[i] = (gid_t) buf[i];
    21			}
    22		}
    23		free(buf);
    24		return rv;
    25	}
    26	*/
    27	import "C"
    28	import (
    29		"fmt"
    30		"unsafe"
    31	)
    32	
    33	func getGroupList(name *C.char, userGID C.gid_t, gids *C.gid_t, n *C.int) C.int {
    34		return C.mygetgrouplist(name, userGID, gids, n)
    35	}
    36	
    37	// groupRetry retries getGroupList with an increasingly large size for n. The
    38	// result is stored in gids.
    39	func groupRetry(username string, name []byte, userGID C.gid_t, gids *[]C.gid_t, n *C.int) error {
    40		*n = C.int(256 * 2)
    41		for {
    42			*gids = make([]C.gid_t, *n)
    43			rv := getGroupList((*C.char)(unsafe.Pointer(&name[0])), userGID, &(*gids)[0], n)
    44			if rv >= 0 {
    45				// n is set correctly
    46				break
    47			}
    48			if *n > maxGroups {
    49				return fmt.Errorf("user: %q is a member of more than %d groups", username, maxGroups)
    50			}
    51			*n = *n * C.int(2)
    52		}
    53		return nil
    54	}
    55	

View as plain text