netatalk  4.4.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/unix.h>
#include <atalk/util.h>
#include <atalk/uuid.h>
#include <atalk/vfs.h>
#include "acl_mappings.h"
#include "acls.h"
#include "auth.h"
#include "desktop.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()

acl_t acl_from_mode ( mode_t mode)
static

◆ acl_permset_to_uarights()

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()

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()

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()

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()

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()

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()

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()

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()

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()

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()

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()

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()

uint32_t posix_permset_to_darwin_rights ( acl_entry_t e,
int is_dir )
static

◆ remove_acl()

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]

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]

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

◆ solaris_acl_rights()

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