posix_acls.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 2,170 行 · 第 1/5 页
C
2,170 行
/* Unix SMB/CIFS implementation. SMB NT Security Descriptor / Unix permission conversion. Copyright (C) Jeremy Allison 1994-2000. Copyright (C) Andreas Gruenbacher 2002. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"extern struct current_user current_user;extern struct generic_mapping file_generic_mapping;#undef DBGC_CLASS#define DBGC_CLASS DBGC_ACLS/**************************************************************************** Data structures representing the internal ACE format.****************************************************************************/enum ace_owner {UID_ACE, GID_ACE, WORLD_ACE};enum ace_attribute {ALLOW_ACE, DENY_ACE}; /* Used for incoming NT ACLS. */typedef union posix_id { uid_t uid; gid_t gid; int world;} posix_id;typedef struct canon_ace { struct canon_ace *next, *prev; SMB_ACL_TAG_T type; mode_t perms; /* Only use S_I(R|W|X)USR mode bits here. */ DOM_SID trustee; enum ace_owner owner_type; enum ace_attribute attr; posix_id unix_ug; BOOL inherited;} canon_ace;#define ALL_ACE_PERMS (S_IRUSR|S_IWUSR|S_IXUSR)/* * EA format of user.SAMBA_PAI (Samba_Posix_Acl_Interitance) * attribute on disk. * * | 1 | 1 | 2 | 2 | .... * +------+------+-------------+---------------------+-------------+--------------------+ * | vers | flag | num_entries | num_default_entries | ..entries.. | default_entries... | * +------+------+-------------+---------------------+-------------+--------------------+ */#define PAI_VERSION_OFFSET 0#define PAI_FLAG_OFFSET 1#define PAI_NUM_ENTRIES_OFFSET 2#define PAI_NUM_DEFAULT_ENTRIES_OFFSET 4#define PAI_ENTRIES_BASE 6#define PAI_VERSION 1#define PAI_ACL_FLAG_PROTECTED 0x1#define PAI_ENTRY_LENGTH 5/* * In memory format of user.SAMBA_PAI attribute. */struct pai_entry { struct pai_entry *next, *prev; enum ace_owner owner_type; posix_id unix_ug; }; struct pai_val { BOOL pai_protected; unsigned int num_entries; struct pai_entry *entry_list; unsigned int num_def_entries; struct pai_entry *def_entry_list;};/************************************************************************ Return a uint32 of the pai_entry principal.************************************************************************/static uint32 get_pai_entry_val(struct pai_entry *paie){ switch (paie->owner_type) { case UID_ACE: DEBUG(10,("get_pai_entry_val: uid = %u\n", (unsigned int)paie->unix_ug.uid )); return (uint32)paie->unix_ug.uid; case GID_ACE: DEBUG(10,("get_pai_entry_val: gid = %u\n", (unsigned int)paie->unix_ug.gid )); return (uint32)paie->unix_ug.gid; case WORLD_ACE: default: DEBUG(10,("get_pai_entry_val: world ace\n")); return (uint32)-1; }}/************************************************************************ Return a uint32 of the entry principal.************************************************************************/static uint32 get_entry_val(canon_ace *ace_entry){ switch (ace_entry->owner_type) { case UID_ACE: DEBUG(10,("get_entry_val: uid = %u\n", (unsigned int)ace_entry->unix_ug.uid )); return (uint32)ace_entry->unix_ug.uid; case GID_ACE: DEBUG(10,("get_entry_val: gid = %u\n", (unsigned int)ace_entry->unix_ug.gid )); return (uint32)ace_entry->unix_ug.gid; case WORLD_ACE: default: DEBUG(10,("get_entry_val: world ace\n")); return (uint32)-1; }}/************************************************************************ Count the inherited entries.************************************************************************/static unsigned int num_inherited_entries(canon_ace *ace_list){ unsigned int num_entries = 0; for (; ace_list; ace_list = ace_list->next) if (ace_list->inherited) num_entries++; return num_entries;}/************************************************************************ Create the on-disk format. Caller must free.************************************************************************/static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL pai_protected, size_t *store_size){ char *pai_buf = NULL; canon_ace *ace_list = NULL; char *entry_offset = NULL; unsigned int num_entries = 0; unsigned int num_def_entries = 0; for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next) if (ace_list->inherited) num_entries++; for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next) if (ace_list->inherited) num_def_entries++; DEBUG(10,("create_pai_buf: num_entries = %u, num_def_entries = %u\n", num_entries, num_def_entries )); *store_size = PAI_ENTRIES_BASE + ((num_entries + num_def_entries)*PAI_ENTRY_LENGTH); pai_buf = SMB_MALLOC(*store_size); if (!pai_buf) { return NULL; } /* Set up the header. */ memset(pai_buf, '\0', PAI_ENTRIES_BASE); SCVAL(pai_buf,PAI_VERSION_OFFSET,PAI_VERSION); SCVAL(pai_buf,PAI_FLAG_OFFSET,(pai_protected ? PAI_ACL_FLAG_PROTECTED : 0)); SSVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET,num_entries); SSVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET,num_def_entries); entry_offset = pai_buf + PAI_ENTRIES_BASE; for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next) { if (ace_list->inherited) { uint8 type_val = (unsigned char)ace_list->owner_type; uint32 entry_val = get_entry_val(ace_list); SCVAL(entry_offset,0,type_val); SIVAL(entry_offset,1,entry_val); entry_offset += PAI_ENTRY_LENGTH; } } for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next) { if (ace_list->inherited) { uint8 type_val = (unsigned char)ace_list->owner_type; uint32 entry_val = get_entry_val(ace_list); SCVAL(entry_offset,0,type_val); SIVAL(entry_offset,1,entry_val); entry_offset += PAI_ENTRY_LENGTH; } } return pai_buf;}/************************************************************************ Store the user.SAMBA_PAI attribute on disk.************************************************************************/static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL pai_protected){ int ret; size_t store_size; char *pai_buf; if (!lp_map_acl_inherit(SNUM(fsp->conn))) return; /* * Don't store if this ACL isn't protected and * none of the entries in it are marked as inherited. */ if (!pai_protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) { /* Instead just remove the attribute if it exists. */ if (fsp->fh->fd != -1) SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME); else SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME); return; } pai_buf = create_pai_buf(file_ace_list, dir_ace_list, pai_protected, &store_size); if (fsp->fh->fd != -1) ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, store_size, 0); else ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, store_size, 0); SAFE_FREE(pai_buf); DEBUG(10,("store_inheritance_attribute:%s for file %s\n", pai_protected ? " (protected)" : "", fsp->fsp_name)); if (ret == -1 && !no_acl_syscall_error(errno)) DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));}/************************************************************************ Delete the in memory inheritance info.************************************************************************/static void free_inherited_info(struct pai_val *pal){ if (pal) { struct pai_entry *paie, *paie_next; for (paie = pal->entry_list; paie; paie = paie_next) { paie_next = paie->next; SAFE_FREE(paie); } for (paie = pal->def_entry_list; paie; paie = paie_next) { paie_next = paie->next; SAFE_FREE(paie); } SAFE_FREE(pal); }}/************************************************************************ Was this ACL protected ?************************************************************************/static BOOL get_protected_flag(struct pai_val *pal){ if (!pal) return False; return pal->pai_protected;}/************************************************************************ Was this ACE inherited ?************************************************************************/static BOOL get_inherited_flag(struct pai_val *pal, canon_ace *ace_entry, BOOL default_ace){ struct pai_entry *paie; if (!pal) return False; /* If the entry exists it is inherited. */ for (paie = (default_ace ? pal->def_entry_list : pal->entry_list); paie; paie = paie->next) { if (ace_entry->owner_type == paie->owner_type && get_entry_val(ace_entry) == get_pai_entry_val(paie)) return True; } return False;}/************************************************************************ Ensure an attribute just read is valid.************************************************************************/static BOOL check_pai_ok(char *pai_buf, size_t pai_buf_data_size){ uint16 num_entries; uint16 num_def_entries; if (pai_buf_data_size < PAI_ENTRIES_BASE) { /* Corrupted - too small. */ return False; } if (CVAL(pai_buf,PAI_VERSION_OFFSET) != PAI_VERSION) return False; num_entries = SVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET); num_def_entries = SVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET); /* Check the entry lists match. */ /* Each entry is 5 bytes (type plus 4 bytes of uid or gid). */ if (((num_entries + num_def_entries)*PAI_ENTRY_LENGTH) + PAI_ENTRIES_BASE != pai_buf_data_size) return False; return True;}/************************************************************************ Convert to in-memory format.************************************************************************/static struct pai_val *create_pai_val(char *buf, size_t size){ char *entry_offset; struct pai_val *paiv = NULL; int i; if (!check_pai_ok(buf, size)) return NULL; paiv = SMB_MALLOC_P(struct pai_val); if (!paiv) return NULL; memset(paiv, '\0', sizeof(struct pai_val)); paiv->pai_protected = (CVAL(buf,PAI_FLAG_OFFSET) == PAI_ACL_FLAG_PROTECTED); paiv->num_entries = SVAL(buf,PAI_NUM_ENTRIES_OFFSET); paiv->num_def_entries = SVAL(buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET); entry_offset = buf + PAI_ENTRIES_BASE; DEBUG(10,("create_pai_val:%s num_entries = %u, num_def_entries = %u\n", paiv->pai_protected ? " (pai_protected)" : "", paiv->num_entries, paiv->num_def_entries )); for (i = 0; i < paiv->num_entries; i++) { struct pai_entry *paie; paie = SMB_MALLOC_P(struct pai_entry); if (!paie) { free_inherited_info(paiv); return NULL; } paie->owner_type = (enum ace_owner)CVAL(entry_offset,0); switch( paie->owner_type) { case UID_ACE: paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1); DEBUG(10,("create_pai_val: uid = %u\n", (unsigned int)paie->unix_ug.uid )); break; case GID_ACE: paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1); DEBUG(10,("create_pai_val: gid = %u\n", (unsigned int)paie->unix_ug.gid )); break; case WORLD_ACE: paie->unix_ug.world = -1; DEBUG(10,("create_pai_val: world ace\n")); break; default: free_inherited_info(paiv); return NULL; } entry_offset += PAI_ENTRY_LENGTH; DLIST_ADD(paiv->entry_list, paie); } for (i = 0; i < paiv->num_def_entries; i++) { struct pai_entry *paie; paie = SMB_MALLOC_P(struct pai_entry); if (!paie) { free_inherited_info(paiv); return NULL; } paie->owner_type = (enum ace_owner)CVAL(entry_offset,0); switch( paie->owner_type) { case UID_ACE: paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1); DEBUG(10,("create_pai_val: (def) uid = %u\n", (unsigned int)paie->unix_ug.uid )); break; case GID_ACE: paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1); DEBUG(10,("create_pai_val: (def) gid = %u\n", (unsigned int)paie->unix_ug.gid )); break; case WORLD_ACE: paie->unix_ug.world = -1; DEBUG(10,("create_pai_val: (def) world ace\n")); break; default: free_inherited_info(paiv); return NULL; } entry_offset += PAI_ENTRY_LENGTH; DLIST_ADD(paiv->def_entry_list, paie); } return paiv;}/************************************************************************ Load the user.SAMBA_PAI attribute.************************************************************************/static struct pai_val *load_inherited_info(files_struct *fsp)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?