netatalk  4.5.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
acls.c File Reference
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <bstrlib.h>
#include <sys/acl.h>
#include <atalk/acl.h>
#include <atalk/adouble.h>
#include <atalk/afp.h>
#include <atalk/cnid.h>
#include <atalk/errchk.h>
#include <atalk/logger.h>
#include <atalk/netatalk_conf.h>
#include <atalk/server_ipc.h>
#include <atalk/unix.h>
#include <atalk/util.h>
#include <atalk/uuid.h>
#include <atalk/vfs.h>
#include "acl_mappings.h"
#include "acls.h"
#include "ad_cache.h"
#include "auth.h"
#include "desktop.h"
#include "dircache.h"
#include "directory.h"
#include "fork.h"
#include "unix.h"
#include "volume.h"

Macros

#define SOLARIS_2_DARWIN   1
 
#define DARWIN_2_SOLARIS   2
 
#define POSIX_DEFAULT_2_DARWIN   3
 
#define POSIX_ACCESS_2_DARWIN   4
 
#define DARWIN_2_POSIX_DEFAULT   5
 
#define DARWIN_2_POSIX_ACCESS   6
 
#define MAP_MASK   31
 
#define IS_DIR   32
 
#define HAS_DEFAULT_ACL   0x01
 
#define HAS_EXT_DEFAULT_ACL   0x02
 

Functions

static int solaris_acl_rights (const AFPObj *obj, const char *path, struct stat *sb, struct maccess *ma, uint32_t *rights_out)
 Compile access rights for a user to one file-system object.
 
static int map_aces_solaris_to_darwin (const ace_t *aces, darwin_ace_t *darwin_aces, int ace_count)
 Maps ACE array from Solaris to Darwin.
 
static int map_aces_darwin_to_solaris (darwin_ace_t *darwin_aces, ace_t *nfsv4_aces, int ace_count)
 Maps ACE array from Darwin to Solaris.
 
static uint32_t posix_permset_to_darwin_rights (acl_entry_t e, int is_dir)
 
static int posix_acl_rights (const AFPObj *obj, const char *path, const struct stat *sb, uint32_t *result)
 Compile access rights for a user to one file-system object.
 
static uint8_t acl_permset_to_uarights (acl_entry_t entry)
 Convert Posix ACL permissions into access rights.
 
static int posix_acls_to_uaperms (const AFPObj *obj, const char *path, struct stat *sb, struct maccess *ma)
 Update FPUnixPrivs for a file-system object on a volume supporting ACLs.
 
static acl_perm_t map_darwin_right_to_posix_permset (uint32_t darwin_ace_rights, int is_dir)
 Map Darwin ACE rights to POSIX 1e perm.
 
static int posix_acl_add_perm (acl_t *aclp, acl_tag_t type, uid_t id, acl_perm_t perm)
 Add a ACL_USER or ACL_GROUP permission to an ACL, extending existing ACEs.
 
static int map_aces_darwin_to_posix (const darwin_ace_t *darwin_aces, acl_t *def_aclp, acl_t *acc_aclp, int ace_count, uint32_t *default_acl_flags)
 Map Darwin ACL to POSIX ACL.
 
static int map_acl_posix_to_darwin (int type, const acl_t acl, darwin_ace_t *darwin_aces)
 Map ACEs from POSIX to Darwin.
 
static int map_acl (int type, void *acl, darwin_ace_t *buf, int ace_count)
 Multiplex ACL mapping (SOLARIS_2_DARWIN, DARWIN_2_SOLARIS, POSIX_2_DARWIN, DARWIN_2_POSIX).
 
static int get_and_map_acl (char *name, char *rbuf, size_t *rbuflen)
 Get ACL from object omitting trivial ACEs.
 
static int remove_acl (const struct vol *vol, const char *path, int dir)
 Removes all non-trivial ACLs from object.
 
static int set_acl (const struct vol *vol, char *name, int inherit, darwin_ace_t *daces, uint32_t ace_count)
 Set ACL.
 
static acl_t acl_from_mode (mode_t mode)
 
static int set_acl (const struct vol *vol, const char *name, int inherit, darwin_ace_t *daces, uint32_t ace_count)
 
static int check_acl_access (const AFPObj *obj, const struct vol *vol, struct dir *dir, const char *path, const uuidp_t uuid, uint32_t requested_rights)
 Checks if a given UUID has requested_rights (type darwin_ace_rights) for path.
 
int afp_access (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 
int afp_getacl (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 
int afp_setacl (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 
int acltoownermode (const AFPObj *obj, const struct vol *vol, char *path, struct stat *st, struct maccess *ma)
 map ACL to user maccess
 

Macro Definition Documentation

◆ DARWIN_2_POSIX_ACCESS

#define DARWIN_2_POSIX_ACCESS   6

◆ DARWIN_2_POSIX_DEFAULT

#define DARWIN_2_POSIX_DEFAULT   5

◆ DARWIN_2_SOLARIS

#define DARWIN_2_SOLARIS   2

◆ HAS_DEFAULT_ACL

#define HAS_DEFAULT_ACL   0x01

◆ HAS_EXT_DEFAULT_ACL

#define HAS_EXT_DEFAULT_ACL   0x02

◆ IS_DIR

#define IS_DIR   32

◆ MAP_MASK

#define MAP_MASK   31

◆ POSIX_ACCESS_2_DARWIN

#define POSIX_ACCESS_2_DARWIN   4

◆ POSIX_DEFAULT_2_DARWIN

#define POSIX_DEFAULT_2_DARWIN   3

◆ SOLARIS_2_DARWIN

#define SOLARIS_2_DARWIN   1

Function Documentation

◆ acl_from_mode()

static acl_t acl_from_mode ( mode_t  mode)
static

◆ acl_permset_to_uarights()

static uint8_t acl_permset_to_uarights ( acl_entry_t  entry)
static

Convert Posix ACL permissions into access rights.

Helper function for posix_acls_to_uaperms() to convert Posix ACL permissions into access rights needed to fill ua_permissions of a FPUnixPrivs structure.

Parameters
[in]entryPosix ACL entry
Returns
access rights

◆ acltoownermode()

int acltoownermode ( const AFPObj obj,
const struct vol vol,
char *  path,
struct stat *  st,
struct maccess ma 
)

map ACL to user maccess

This is the magic function that makes ACLs usable by calculating the access granted by ACEs to the logged in user.

◆ afp_access()

int afp_access ( AFPObj obj,
char *  ibuf,
size_t  ibuflen,
char *  rbuf,
size_t *  rbuflen 
)

◆ afp_getacl()

int afp_getacl ( AFPObj obj,
char *  ibuf,
size_t  ibuflen,
char *  rbuf,
size_t *  rbuflen 
)

◆ afp_setacl()

int afp_setacl ( AFPObj obj,
char *  ibuf,
size_t  ibuflen,
char *  rbuf,
size_t *  rbuflen 
)

◆ check_acl_access()

static int check_acl_access ( const AFPObj obj,
const struct vol vol,
struct dir dir,
const char *  path,
const uuidp_t  uuid,
uint32_t  requested_rights 
)
static

Checks if a given UUID has requested_rights (type darwin_ace_rights) for path.

Note
this gets called frequently and is a good place for optimizations !
Parameters
[in]objAFP object
[in]volvolume
[in,out]dirdirectory
[in]pathpath to filesystem object
[in]uuidUUID of user
[in]requested_rightsrequested Darwin ACE
Returns
AFP result code

◆ get_and_map_acl()

static int get_and_map_acl ( char *  name,
char *  rbuf,
size_t *  rbuflen 
)
static

Get ACL from object omitting trivial ACEs.

Map to Darwin ACL style and store Darwin ACL at rbuf. Add length of ACL written to rbuf to *rbuflen.

Returns
0 on success, -1 on error.

◆ map_aces_darwin_to_posix()

static int map_aces_darwin_to_posix ( const darwin_ace_t darwin_aces,
acl_t *  def_aclp,
acl_t *  acc_aclp,
int  ace_count,
uint32_t *  default_acl_flags 
)
static

Map Darwin ACL to POSIX ACL.

aclp must point to a acl_init'ed acl_t or an acl_t that can e.g. contain default ACEs. Mapping pecularities:

  • we create a default ace (which inherits to files and dirs) if either DARWIN_ACE_FLAGS_FILE_INHERIT or DARWIN_ACE_FLAGS_DIRECTORY_INHERIT is requested
  • we throw away DARWIN_ACE_FLAGS_LIMIT_INHERIT (can't be mapped), thus the ACL will not be limited
Parameters
[in]darwin_acespointer to darwin_aces buffer
[in,out]def_aclpdirectories: pointer to an initialized acl_t with the default acl files: *def_aclp will be NULL
[in,out]acc_aclppointer to an initialized acl_t with the access acl
[in]ace_countnumber of ACEs in darwin_aces buffer
[in,out]default_acl_flagsflags to indicate if the object has a basic default acl or an extended default acl.
Returns
0 on success storing the result in aclp, -1 on error. default_acl_flags is set to HAS_DEFAULT_ACL|HAS_EXT_DEFAULT_ACL in case there is at least one extended default ace. Otherwise default_acl_flags is left unchanged.

◆ map_aces_darwin_to_solaris()

static int map_aces_darwin_to_solaris ( darwin_ace_t darwin_aces,
ace_t *  nfsv4_aces,
int  ace_count 
)
static

Maps ACE array from Darwin to Solaris.

Returns
number of mapped ACEs or -1 on error.
Note
Darwin ACEs are expected in network byte order.
All errors while mapping (e.g. getting UUIDs from LDAP) are fatal.

◆ map_aces_solaris_to_darwin()

static int map_aces_solaris_to_darwin ( const ace_t *  aces,
darwin_ace_t darwin_aces,
int  ace_count 
)
static

Maps ACE array from Solaris to Darwin.

Returns
number of mapped ACEs or -1 on error.
Note
Darwin ACEs are stored in network byte order.
All errors while mapping (e.g. getting UUIDs from LDAP) are fatal.

◆ map_acl()

static int map_acl ( int  type,
void *  acl,
darwin_ace_t buf,
int  ace_count 
)
static

Multiplex ACL mapping (SOLARIS_2_DARWIN, DARWIN_2_SOLARIS, POSIX_2_DARWIN, DARWIN_2_POSIX).

Reads from 'aces' buffer, writes to 'rbuf' buffer. Caller must provide buffer. Darwin ACEs are read and written in network byte order. Needs to know how many ACEs are in the ACL (ace_count) for Solaris ACLs. Ignores trivial ACEs.

Returns
no of mapped ACEs or -1 on error.

◆ map_acl_posix_to_darwin()

static int map_acl_posix_to_darwin ( int  type,
const acl_t  acl,
darwin_ace_t darwin_aces 
)
static

Map ACEs from POSIX to Darwin.

Returns
number of mapped ACES, -1 on error.
Note
type is either POSIX_DEFAULT_2_DARWIN or POSIX_ACCESS_2_DARWIN, cf. acl_get_file.

◆ map_darwin_right_to_posix_permset()

static acl_perm_t map_darwin_right_to_posix_permset ( uint32_t  darwin_ace_rights,
int  is_dir 
)
static

Map Darwin ACE rights to POSIX 1e perm.

We can only map few rights:

  • DARWIN_ACE_READ_DATA -> ACL_READ
  • DARWIN_ACE_WRITE_DATA -> ACL_WRITE
  • DARWIN_ACE_DELETE_CHILD & (is_dir == 1) -> ACL_WRITE
  • DARWIN_ACE_EXECUTE -> ACL_EXECUTE
Parameters
[in,out]darwin_ace_rightsresult of the mapping
[in]is_dir1 for dirs, 0 for files
Returns
mapping result as acl_perm_t, -1 on error

◆ posix_acl_add_perm()

static int posix_acl_add_perm ( acl_t *  aclp,
acl_tag_t  type,
uid_t  id,
acl_perm_t  perm 
)
static

Add a ACL_USER or ACL_GROUP permission to an ACL, extending existing ACEs.

Add a permission of "type" for user or group "id" to an ACL. Scan the ACL for existing permissions for this type/id, if there is one add the perm, otherwise create a new ACL entry. perm can be or'ed ACL_READ, ACL_WRITE and ACL_EXECUTE.

Parameters
[in,out]aclppointer to ACL
[in]typeacl_tag_t of ACL_USER or ACL_GROUP
[in]iduid_t uid for ACL_USER, or gid casted to uid_t for ACL_GROUP
[in]permacl_perm_t permissions to add
Returns
0 on success, -1 on failure

◆ posix_acl_rights()

static int posix_acl_rights ( const AFPObj obj,
const char *  path,
const struct stat *  sb,
uint32_t *  result 
)
static

Compile access rights for a user to one file-system object.

This combines combines all access rights for a user to one fs-object and returns the result as a Darwin allowed rights ACE. This must honor trivial ACEs which are a mode_t mapping.

Parameters
[in]objhandle
[in]pathpath to filesystem object
[in]sbstruct stat of path
[in,out]resultresulting Darwin allow ACE
Returns
0 or -1 on error

◆ posix_acls_to_uaperms()

static int posix_acls_to_uaperms ( const AFPObj obj,
const char *  path,
struct stat *  sb,
struct maccess ma 
)
static

Update FPUnixPrivs for a file-system object on a volume supporting ACLs.

Checks permissions granted by ACLS for a user to one fs-object and updates user and group permissions in given struct maccess. As OS X doesn't conform to Posix 1003.1e Draft 17 it expects proper group permissions in st_mode of struct stat even if the fs-object has an ACL_MASK entry, st_mode gets modified to properly reflect group permissions.

Parameters
[in]objhandle
[in]pathpath to filesystem object
[in,out]sbstruct stat of path
[in,out]mastruct maccess of path
Returns
0 or -1 on error

◆ posix_permset_to_darwin_rights()

static uint32_t posix_permset_to_darwin_rights ( acl_entry_t  e,
int  is_dir 
)
static

◆ remove_acl()

static int remove_acl ( const struct vol vol,
const char *  path,
int  dir 
)
static

Removes all non-trivial ACLs from object.

Returns
full AFPERR code.

◆ set_acl() [1/2]

static int set_acl ( const struct vol vol,
char *  name,
int  inherit,
darwin_ace_t daces,
uint32_t  ace_count 
)
static

Set ACL.

Note
Subtleties:
  • the client sends a complete list of ACEs, not only new ones. So we don't need to do any combination business (one exception being 'kFileSec_Inherit': see next)
  • client might request that we add inherited ACEs via 'kFileSec_Inherit'. We will store inherited ACEs first, which is Darwins canonical order.
Returns
AFPerror code

◆ set_acl() [2/2]

static int set_acl ( const struct vol vol,
const char *  name,
int  inherit,
darwin_ace_t daces,
uint32_t  ace_count 
)
static

◆ solaris_acl_rights()

static int solaris_acl_rights ( const AFPObj obj,
const char *  path,
struct stat *  sb,
struct maccess ma,
uint32_t *  rights_out 
)
static

Compile access rights for a user to one file-system object.

This combines all access rights for a user to one fs-object and returns the result as a Darwin allowed rights ACE. This must honor trivial ACEs which are a mode_t mapping.

Parameters
[in]objhandle
[in]pathpath to filesystem object
[in,out]sbstruct stat of path
[in,out]maUARights struct
[out]rights_outmapped Darwin ACL rights
Returns
0 or -1 on error