netatalk: acls.c File Reference

netatalk 4.5.1
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 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_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] | entry | Posix 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] | obj | AFP object
  [in] | vol | volume
  [in,out] | dir | directory
  [in] | path | path to filesystem object
  [in] | uuid | UUID of user
  [in] | requested_rights | requested 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_aces | pointer to darwin_aces buffer
  [in,out] | def_aclp | directories: pointer to an initialized acl_t with the default acl files: *def_aclp will be NULL
  [in,out] | acc_aclp | pointer to an initialized acl_t with the access acl
  [in] | ace_count | number of ACEs in darwin_aces buffer
  [in,out] | default_acl_flags | flags 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_rights | result of the mapping
  [in] | is_dir | 1 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] | aclp | pointer to ACL
  [in] | type | acl_tag_t of ACL_USER or ACL_GROUP
  [in] | id | uid_t uid for ACL_USER, or gid casted to uid_t for ACL_GROUP
  [in] | perm | acl_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] | obj | handle
  [in] | path | path to filesystem object
  [in] | sb | struct stat of path
  [in,out] | result | resulting 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] | obj | handle
  [in] | path | path to filesystem object
  [in,out] | sb | struct stat of path
  [in,out] | ma | struct 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] | obj | handle
  [in] | path | path to filesystem object
  [in,out] | sb | struct stat of path
  [in,out] | ma | UARights struct
  [out] | rights_out | mapped Darwin ACL rights

Returns
  0 or -1 on error