smbd/posix_acls.c

ソースコードを見る。

データ構造

union  posix_id
struct  canon_ace
struct  pai_entry
struct  pai_val

列挙型

enum  ace_owner { UID_ACE, GID_ACE, WORLD_ACE }
enum  ace_attribute { ALLOW_ACE, DENY_ACE }

関数

static uint32 get_pai_entry_val (struct pai_entry *paie)
static uint32 get_entry_val (canon_ace *ace_entry)
static unsigned int num_inherited_entries (canon_ace *ace_list)
static char * create_pai_buf (canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL pai_protected, size_t *store_size)
static void store_inheritance_attributes (files_struct *fsp, canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL pai_protected)
static void free_inherited_info (struct pai_val *pal)
static BOOL get_protected_flag (struct pai_val *pal)
static BOOL get_inherited_flag (struct pai_val *pal, canon_ace *ace_entry, BOOL default_ace)
static BOOL check_pai_ok (char *pai_buf, size_t pai_buf_data_size)
static struct pai_valcreate_pai_val (char *buf, size_t size)
static struct pai_valload_inherited_info (files_struct *fsp)
static size_t count_canon_ace_list (canon_ace *list_head)
static void free_canon_ace_list (canon_ace *list_head)
static canon_acedup_canon_ace (canon_ace *src_ace)
static void print_canon_ace (canon_ace *pace, int num)
static void print_canon_ace_list (const char *name, canon_ace *ace_list)
static mode_t convert_permset_to_mode_t (connection_struct *conn, SMB_ACL_PERMSET_T permset)
static mode_t unix_perms_to_acl_perms (mode_t mode, int r_mask, int w_mask, int x_mask)
static int map_acl_perms_to_permset (connection_struct *conn, mode_t mode, SMB_ACL_PERMSET_T *p_permset)
static void create_file_sids (SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
static BOOL identity_in_ace_equal (canon_ace *ace1, canon_ace *ace2)
static void merge_aces (canon_ace **pp_list_head)
static BOOL nt4_compatible_acls (void)
static SEC_ACCESS map_canon_ace_perms (int snum, int *pacl_type, mode_t perms, BOOL directory_ace)
static mode_t map_nt_perms (uint32 *mask, int type)
BOOL unpack_nt_owners (int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd)
static void apply_default_perms (files_struct *fsp, canon_ace *pace, mode_t type)
static BOOL uid_entry_in_group (canon_ace *uid_ace, canon_ace *group_ace)
static BOOL ensure_canon_entry_valid (canon_ace **pp_ace, files_struct *fsp, const DOM_SID *pfile_owner_sid, const DOM_SID *pfile_grp_sid, SMB_STRUCT_STAT *pst, BOOL setting_acl)
static void check_owning_objs (canon_ace *ace, DOM_SID *pfile_owner_sid, DOM_SID *pfile_grp_sid)
static BOOL create_canon_ace_lists (files_struct *fsp, SMB_STRUCT_STAT *pst, DOM_SID *pfile_owner_sid, DOM_SID *pfile_grp_sid, canon_ace **ppfile_ace, canon_ace **ppdir_ace, SEC_ACL *dacl)
static void process_deny_list (canon_ace **pp_ace_list)
static mode_t create_default_mode (files_struct *fsp, BOOL interitable_mode)
static BOOL unpack_canon_ace (files_struct *fsp, SMB_STRUCT_STAT *pst, DOM_SID *pfile_owner_sid, DOM_SID *pfile_grp_sid, canon_ace **ppfile_ace, canon_ace **ppdir_ace, uint32 security_info_sent, SEC_DESC *psd)
static void arrange_posix_perms (char *filename, canon_ace **pp_list_head)
static canon_acecanonicalise_acl (files_struct *fsp, SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf, const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
static BOOL current_user_in_group (gid_t gid)
static BOOL acl_group_override (connection_struct *conn, gid_t prim_gid, const char *fname)
static BOOL set_canon_ace_list (files_struct *fsp, canon_ace *the_ace, BOOL default_ace, gid_t prim_gid, BOOL *pacl_set_support)
static struct canon_acecanon_ace_entry_for (struct canon_ace *list, SMB_ACL_TAG_T type, posix_id *id)
SMB_ACL_T free_empty_sys_acl (connection_struct *conn, SMB_ACL_T the_acl)
static BOOL convert_canon_ace_to_posix_perms (files_struct *fsp, canon_ace *file_ace_list, mode_t *posix_perms)
static size_t merge_default_aces (SEC_ACE *nt_ace_list, size_t num_aces)
size_t get_nt_acl (files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
int try_chown (connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
static NTSTATUS append_parent_acl (files_struct *fsp, SMB_STRUCT_STAT *psbuf, SEC_DESC *psd, SEC_DESC **pp_new_sd)
BOOL set_nt_acl (files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
int get_acl_group_bits (connection_struct *conn, const char *fname, mode_t *mode)
static int chmod_acl_internals (connection_struct *conn, SMB_ACL_T posix_acl, mode_t mode)
static int copy_access_acl (connection_struct *conn, const char *from, const char *to, mode_t mode)
int chmod_acl (connection_struct *conn, const char *name, mode_t mode)
int inherit_access_acl (connection_struct *conn, const char *inherit_from_dir, const char *name, mode_t mode)
int fchmod_acl (files_struct *fsp, int fd, mode_t mode)
BOOL directory_has_default_acl (connection_struct *conn, const char *fname)
static BOOL unix_ex_wire_to_permset (connection_struct *conn, unsigned char wire_perm, SMB_ACL_PERMSET_T *p_permset)
static BOOL unix_ex_wire_to_tagtype (unsigned char wire_tt, SMB_ACL_TAG_T *p_tt)
static SMB_ACL_T create_posix_acl_from_wire (connection_struct *conn, uint16 num_acls, const char *pdata)
BOOL set_unix_posix_default_acl (connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint16 num_def_acls, const char *pdata)
static BOOL remove_posix_acl (connection_struct *conn, files_struct *fsp, const char *fname)
BOOL set_unix_posix_acl (connection_struct *conn, files_struct *fsp, const char *fname, uint16 num_acls, const char *pdata)
static NTSTATUS conn_get_nt_acl (TALLOC_CTX *mem_ctx, struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, struct security_descriptor_info **psd)
static BOOL can_access_file_acl (struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint32_t access_mask)
BOOL can_delete_file_in_directory (connection_struct *conn, const char *fname)
BOOL can_access_file (connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 access_mask)
BOOL can_write_to_file (connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
SEC_DESCget_nt_acl_no_snum (TALLOC_CTX *ctx, const char *fname)

変数

current_user current_user
generic_mapping file_generic_mapping


列挙型

enum ace_owner

列挙型の値:
UID_ACE 
GID_ACE 
WORLD_ACE 

posix_acls.c34 行で定義されています。

enum ace_attribute

列挙型の値:
ALLOW_ACE 
DENY_ACE 

posix_acls.c35 行で定義されています。

00035 {ALLOW_ACE, DENY_ACE}; /* Used for incoming NT ACLS. */


関数

static uint32 get_pai_entry_val ( struct pai_entry paie  )  [static]

posix_acls.c98 行で定義されています。

参照先 posix_id::gidGID_ACEpai_entry::owner_typeposix_id::uidUID_ACEpai_entry::unix_ugWORLD_ACE.

参照元 get_inherited_flag().

00099 {
00100         switch (paie->owner_type) {
00101                 case UID_ACE:
00102                         DEBUG(10,("get_pai_entry_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
00103                         return (uint32)paie->unix_ug.uid;
00104                 case GID_ACE:
00105                         DEBUG(10,("get_pai_entry_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
00106                         return (uint32)paie->unix_ug.gid;
00107                 case WORLD_ACE:
00108                 default:
00109                         DEBUG(10,("get_pai_entry_val: world ace\n"));
00110                         return (uint32)-1;
00111         }
00112 }

static uint32 get_entry_val ( canon_ace ace_entry  )  [static]

posix_acls.c118 行で定義されています。

参照先 posix_id::gidGID_ACEcanon_ace::owner_typeposix_id::uidUID_ACEcanon_ace::unix_ugWORLD_ACE.

参照元 create_pai_buf()get_inherited_flag().

00119 {
00120         switch (ace_entry->owner_type) {
00121                 case UID_ACE:
00122                         DEBUG(10,("get_entry_val: uid = %u\n", (unsigned int)ace_entry->unix_ug.uid ));
00123                         return (uint32)ace_entry->unix_ug.uid;
00124                 case GID_ACE:
00125                         DEBUG(10,("get_entry_val: gid = %u\n", (unsigned int)ace_entry->unix_ug.gid ));
00126                         return (uint32)ace_entry->unix_ug.gid;
00127                 case WORLD_ACE:
00128                 default:
00129                         DEBUG(10,("get_entry_val: world ace\n"));
00130                         return (uint32)-1;
00131         }
00132 }

static unsigned int num_inherited_entries ( canon_ace ace_list  )  [static]

posix_acls.c138 行で定義されています。

参照先 canon_ace::inheritedcanon_ace::next.

参照元 store_inheritance_attributes().

00139 {
00140         unsigned int num_entries = 0;
00141 
00142         for (; ace_list; ace_list = ace_list->next)
00143                 if (ace_list->inherited)
00144                         num_entries++;
00145         return num_entries;
00146 }

static char* create_pai_buf ( canon_ace file_ace_list,
canon_ace dir_ace_list,
BOOL  pai_protected,
size_t *  store_size 
) [static]

posix_acls.c152 行で定義されています。

参照先 get_entry_val()canon_ace::inheritedcanon_ace::nextcanon_ace::owner_type.

参照元 store_inheritance_attributes().

00153 {
00154         char *pai_buf = NULL;
00155         canon_ace *ace_list = NULL;
00156         char *entry_offset = NULL;
00157         unsigned int num_entries = 0;
00158         unsigned int num_def_entries = 0;
00159 
00160         for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next)
00161                 if (ace_list->inherited)
00162                         num_entries++;
00163 
00164         for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next)
00165                 if (ace_list->inherited)
00166                         num_def_entries++;
00167 
00168         DEBUG(10,("create_pai_buf: num_entries = %u, num_def_entries = %u\n", num_entries, num_def_entries ));
00169 
00170         *store_size = PAI_ENTRIES_BASE + ((num_entries + num_def_entries)*PAI_ENTRY_LENGTH);
00171 
00172         pai_buf = (char *)SMB_MALLOC(*store_size);
00173         if (!pai_buf) {
00174                 return NULL;
00175         }
00176 
00177         /* Set up the header. */
00178         memset(pai_buf, '\0', PAI_ENTRIES_BASE);
00179         SCVAL(pai_buf,PAI_VERSION_OFFSET,PAI_VERSION);
00180         SCVAL(pai_buf,PAI_FLAG_OFFSET,(pai_protected ? PAI_ACL_FLAG_PROTECTED : 0));
00181         SSVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET,num_entries);
00182         SSVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET,num_def_entries);
00183 
00184         entry_offset = pai_buf + PAI_ENTRIES_BASE;
00185 
00186         for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next) {
00187                 if (ace_list->inherited) {
00188                         uint8 type_val = (unsigned char)ace_list->owner_type;
00189                         uint32 entry_val = get_entry_val(ace_list);
00190 
00191                         SCVAL(entry_offset,0,type_val);
00192                         SIVAL(entry_offset,1,entry_val);
00193                         entry_offset += PAI_ENTRY_LENGTH;
00194                 }
00195         }
00196 
00197         for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next) {
00198                 if (ace_list->inherited) {
00199                         uint8 type_val = (unsigned char)ace_list->owner_type;
00200                         uint32 entry_val = get_entry_val(ace_list);
00201 
00202                         SCVAL(entry_offset,0,type_val);
00203                         SIVAL(entry_offset,1,entry_val);
00204                         entry_offset += PAI_ENTRY_LENGTH;
00205                 }
00206         }
00207 
00208         return pai_buf;
00209 }

static void store_inheritance_attributes ( files_struct fsp,
canon_ace file_ace_list,
canon_ace dir_ace_list,
BOOL  pai_protected 
) [static]

posix_acls.c215 行で定義されています。

参照先 files_struct::conncreate_pai_buf()errnofd_handle::fdfiles_struct::fhfiles_struct::fsp_nameno_acl_syscall_error()num_inherited_entries()strerror().

参照元 set_nt_acl().

00217 {
00218         int ret;
00219         size_t store_size;
00220         char *pai_buf;
00221 
00222         if (!lp_map_acl_inherit(SNUM(fsp->conn)))
00223                 return;
00224 
00225         /*
00226          * Don't store if this ACL isn't protected and
00227          * none of the entries in it are marked as inherited.
00228          */
00229 
00230         if (!pai_protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) {
00231                 /* Instead just remove the attribute if it exists. */
00232                 if (fsp->fh->fd != -1)
00233                         SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME);
00234                 else
00235                         SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
00236                 return;
00237         }
00238 
00239         pai_buf = create_pai_buf(file_ace_list, dir_ace_list, pai_protected, &store_size);
00240 
00241         if (fsp->fh->fd != -1)
00242                 ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
00243                                 pai_buf, store_size, 0);
00244         else
00245                 ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
00246                                 pai_buf, store_size, 0);
00247 
00248         SAFE_FREE(pai_buf);
00249 
00250         DEBUG(10,("store_inheritance_attribute:%s for file %s\n", pai_protected ? " (protected)" : "", fsp->fsp_name));
00251         if (ret == -1 && !no_acl_syscall_error(errno))
00252                 DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));
00253 }

static void free_inherited_info ( struct pai_val pal  )  [static]

posix_acls.c259 行で定義されています。

参照先 pai_val::def_entry_listpai_val::entry_listpai_entry::next.

参照元 create_pai_val()get_nt_acl().

00260 {
00261         if (pal) {
00262                 struct pai_entry *paie, *paie_next;
00263                 for (paie = pal->entry_list; paie; paie = paie_next) {
00264                         paie_next = paie->next;
00265                         SAFE_FREE(paie);
00266                 }
00267                 for (paie = pal->def_entry_list; paie; paie = paie_next) {
00268                         paie_next = paie->next;
00269                         SAFE_FREE(paie);
00270                 }
00271                 SAFE_FREE(pal);
00272         }
00273 }

static BOOL get_protected_flag ( struct pai_val pal  )  [static]

posix_acls.c279 行で定義されています。

参照先 pai_val::pai_protected.

参照元 get_nt_acl().

00280 {
00281         if (!pal)
00282                 return False;
00283         return pal->pai_protected;
00284 }

static BOOL get_inherited_flag ( struct pai_val pal,
canon_ace ace_entry,
BOOL  default_ace 
) [static]

posix_acls.c290 行で定義されています。

参照先 pai_val::def_entry_listpai_val::entry_listget_entry_val()get_pai_entry_val()pai_entry::nextpai_entry::owner_typecanon_ace::owner_type.

参照元 canonicalise_acl().

00291 {
00292         struct pai_entry *paie;
00293 
00294         if (!pal)
00295                 return False;
00296 
00297         /* If the entry exists it is inherited. */
00298         for (paie = (default_ace ? pal->def_entry_list : pal->entry_list); paie; paie = paie->next) {
00299                 if (ace_entry->owner_type == paie->owner_type &&
00300                                 get_entry_val(ace_entry) == get_pai_entry_val(paie))
00301                         return True;
00302         }
00303         return False;
00304 }

static BOOL check_pai_ok ( char *  pai_buf,
size_t  pai_buf_data_size 
) [static]

posix_acls.c310 行で定義されています。

参照元 create_pai_val().

00311 {
00312         uint16 num_entries;
00313         uint16 num_def_entries;
00314 
00315         if (pai_buf_data_size < PAI_ENTRIES_BASE) {
00316                 /* Corrupted - too small. */
00317                 return False;
00318         }
00319 
00320         if (CVAL(pai_buf,PAI_VERSION_OFFSET) != PAI_VERSION)
00321                 return False;
00322 
00323         num_entries = SVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET);
00324         num_def_entries = SVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
00325 
00326         /* Check the entry lists match. */
00327         /* Each entry is 5 bytes (type plus 4 bytes of uid or gid). */
00328 
00329         if (((num_entries + num_def_entries)*PAI_ENTRY_LENGTH) + PAI_ENTRIES_BASE != pai_buf_data_size)
00330                 return False;
00331 
00332         return True;
00333 }

static struct pai_val* create_pai_val ( char *  buf,
size_t  size 
) [static]

posix_acls.c340 行で定義されています。

参照先 check_pai_ok()pai_val::def_entry_listpai_val::entry_listfree_inherited_info()GID_ACEpai_val::num_def_entriespai_val::num_entriespai_val::pai_protectedUID_ACEWORLD_ACE.

参照元 load_inherited_info().

00341 {
00342         char *entry_offset;
00343         struct pai_val *paiv = NULL;
00344         int i;
00345 
00346         if (!check_pai_ok(buf, size))
00347                 return NULL;
00348 
00349         paiv = SMB_MALLOC_P(struct pai_val);
00350         if (!paiv)
00351                 return NULL;
00352 
00353         memset(paiv, '\0', sizeof(struct pai_val));
00354 
00355         paiv->pai_protected = (CVAL(buf,PAI_FLAG_OFFSET) == PAI_ACL_FLAG_PROTECTED);
00356 
00357         paiv->num_entries = SVAL(buf,PAI_NUM_ENTRIES_OFFSET);
00358         paiv->num_def_entries = SVAL(buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
00359 
00360         entry_offset = buf + PAI_ENTRIES_BASE;
00361 
00362         DEBUG(10,("create_pai_val:%s num_entries = %u, num_def_entries = %u\n",
00363                         paiv->pai_protected ? " (pai_protected)" : "", paiv->num_entries, paiv->num_def_entries ));
00364 
00365         for (i = 0; i < paiv->num_entries; i++) {
00366                 struct pai_entry *paie;
00367 
00368                 paie = SMB_MALLOC_P(struct pai_entry);
00369                 if (!paie) {
00370                         free_inherited_info(paiv);
00371                         return NULL;
00372                 }
00373 
00374                 paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
00375                 switch( paie->owner_type) {
00376                         case UID_ACE:
00377                                 paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
00378                                 DEBUG(10,("create_pai_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
00379                                 break;
00380                         case GID_ACE:
00381                                 paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
00382                                 DEBUG(10,("create_pai_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
00383                                 break;
00384                         case WORLD_ACE:
00385                                 paie->unix_ug.world = -1;
00386                                 DEBUG(10,("create_pai_val: world ace\n"));
00387                                 break;
00388                         default:
00389                                 free_inherited_info(paiv);
00390                                 return NULL;
00391                 }
00392                 entry_offset += PAI_ENTRY_LENGTH;
00393                 DLIST_ADD(paiv->entry_list, paie);
00394         }
00395 
00396         for (i = 0; i < paiv->num_def_entries; i++) {
00397                 struct pai_entry *paie;
00398 
00399                 paie = SMB_MALLOC_P(struct pai_entry);
00400                 if (!paie) {
00401                         free_inherited_info(paiv);
00402                         return NULL;
00403                 }
00404 
00405                 paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
00406                 switch( paie->owner_type) {
00407                         case UID_ACE:
00408                                 paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
00409                                 DEBUG(10,("create_pai_val: (def) uid = %u\n", (unsigned int)paie->unix_ug.uid ));
00410                                 break;
00411                         case GID_ACE:
00412                                 paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
00413                                 DEBUG(10,("create_pai_val: (def) gid = %u\n", (unsigned int)paie->unix_ug.gid ));
00414                                 break;
00415                         case WORLD_ACE:
00416                                 paie->unix_ug.world = -1;
00417                                 DEBUG(10,("create_pai_val: (def) world ace\n"));
00418                                 break;
00419                         default:
00420                                 free_inherited_info(paiv);
00421                                 return NULL;
00422                 }
00423                 entry_offset += PAI_ENTRY_LENGTH;
00424                 DLIST_ADD(paiv->def_entry_list, paie);
00425         }
00426 
00427         return paiv;
00428 }

static struct pai_val* load_inherited_info ( files_struct fsp  )  [static]

posix_acls.c434 行で定義されています。

参照先 files_struct::conncreate_pai_val()errnofd_handle::fdfiles_struct::fhfiles_struct::fsp_namepai_val::pai_protectedstrerror().

参照元 get_nt_acl().

00435 {
00436         char *pai_buf;
00437         size_t pai_buf_size = 1024;
00438         struct pai_val *paiv = NULL;
00439         ssize_t ret;
00440 
00441         if (!lp_map_acl_inherit(SNUM(fsp->conn)))
00442                 return NULL;
00443 
00444         if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL)
00445                 return NULL;
00446 
00447         do {
00448                 if (fsp->fh->fd != -1)
00449                         ret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
00450                                         pai_buf, pai_buf_size);
00451                 else
00452                         ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
00453                                         pai_buf, pai_buf_size);
00454 
00455                 if (ret == -1) {
00456                         if (errno != ERANGE) {
00457                                 break;
00458                         }
00459                         /* Buffer too small - enlarge it. */
00460                         pai_buf_size *= 2;
00461                         SAFE_FREE(pai_buf);
00462                         if (pai_buf_size > 1024*1024) {
00463                                 return NULL; /* Limit malloc to 1mb. */
00464                         }
00465                         if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL)
00466                                 return NULL;
00467                 }
00468         } while (ret == -1);
00469 
00470         DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name));
00471 
00472         if (ret == -1) {
00473                 /* No attribute or not supported. */
00474 #if defined(ENOATTR)
00475                 if (errno != ENOATTR)
00476                         DEBUG(10,("load_inherited_info: Error %s\n", strerror(errno) ));
00477 #else
00478                 if (errno != ENOSYS)
00479                         DEBUG(10,("load_inherited_info: Error %s\n", strerror(errno) ));
00480 #endif
00481                 SAFE_FREE(pai_buf);
00482                 return NULL;
00483         }
00484 
00485         paiv = create_pai_val(pai_buf, ret);
00486 
00487         if (paiv && paiv->pai_protected)
00488                 DEBUG(10,("load_inherited_info: ACL is protected for file %s\n", fsp->fsp_name));
00489 
00490         SAFE_FREE(pai_buf);
00491         return paiv;
00492 }

static size_t count_canon_ace_list ( canon_ace list_head  )  [static]

posix_acls.c502 行で定義されています。

参照先 canon_ace::next.

参照元 check_owning_objs()convert_canon_ace_to_posix_perms()get_nt_acl()set_canon_ace_list().

00503 {
00504         size_t count = 0;
00505         canon_ace *ace;
00506 
00507         for (ace = list_head; ace; ace = ace->next)
00508                 count++;
00509 
00510         return count;
00511 }

static void free_canon_ace_list ( canon_ace list_head  )  [static]

posix_acls.c517 行で定義されています。

参照先 list().

参照元 get_nt_acl()process_deny_list()set_nt_acl()unpack_canon_ace().

00518 {
00519         canon_ace *list, *next;
00520 
00521         for (list = list_head; list; list = next) {
00522                 next = list->next;
00523                 DLIST_REMOVE(list_head, list);
00524                 SAFE_FREE(list);
00525         }
00526 }

static canon_ace* dup_canon_ace ( canon_ace src_ace  )  [static]

posix_acls.c532 行で定義されています。

参照先 canon_ace::nextcanon_ace::prev.

00533 {
00534         canon_ace *dst_ace = SMB_MALLOC_P(canon_ace);
00535 
00536         if (dst_ace == NULL)
00537                 return NULL;
00538 
00539         *dst_ace = *src_ace;
00540         dst_ace->prev = dst_ace->next = NULL;
00541         return dst_ace;
00542 }

static void print_canon_ace ( canon_ace pace,
int  num 
) [static]

posix_acls.c548 行で定義されています。

参照先 ALLOW_ACEcanon_ace::attrdbgtext()posix_id::gidGID_ACEgidtoname()canon_ace::inheritedcanon_ace::owner_typecanon_ace::permssid_to_string()SMB_ACL_GROUPSMB_ACL_GROUP_OBJSMB_ACL_OTHERSMB_ACL_USERSMB_ACL_USER_OBJcanon_ace::trusteecanon_ace::typeposix_id::uidUID_ACEuidtoname()canon_ace::unix_ug.

参照元 canonicalise_acl()merge_aces()print_canon_ace_list()set_canon_ace_list().

00549 {
00550         fstring str;
00551 
00552         dbgtext( "canon_ace index %d. Type = %s ", num, pace->attr == ALLOW_ACE ? "allow" : "deny" );
00553         dbgtext( "SID = %s ", sid_to_string( str, &pace->trustee));
00554         if (pace->owner_type == UID_ACE) {
00555                 const char *u_name = uidtoname(pace->unix_ug.uid);
00556                 dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, u_name );
00557         } else if (pace->owner_type == GID_ACE) {
00558                 char *g_name = gidtoname(pace->unix_ug.gid);
00559                 dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, g_name );
00560         } else
00561                 dbgtext( "other ");
00562         switch (pace->type) {
00563                 case SMB_ACL_USER:
00564                         dbgtext( "SMB_ACL_USER ");
00565                         break;
00566                 case SMB_ACL_USER_OBJ:
00567                         dbgtext( "SMB_ACL_USER_OBJ ");
00568                         break;
00569                 case SMB_ACL_GROUP:
00570                         dbgtext( "SMB_ACL_GROUP ");
00571                         break;
00572                 case SMB_ACL_GROUP_OBJ:
00573                         dbgtext( "SMB_ACL_GROUP_OBJ ");
00574                         break;
00575                 case SMB_ACL_OTHER:
00576                         dbgtext( "SMB_ACL_OTHER ");
00577                         break;
00578                 default:
00579                         dbgtext( "MASK " );
00580                         break;
00581         }
00582         if (pace->inherited)
00583                 dbgtext( "(inherited) ");
00584         dbgtext( "perms ");
00585         dbgtext( "%c", pace->perms & S_IRUSR ? 'r' : '-');
00586         dbgtext( "%c", pace->perms & S_IWUSR ? 'w' : '-');
00587         dbgtext( "%c\n", pace->perms & S_IXUSR ? 'x' : '-');
00588 }

static void print_canon_ace_list ( const char *  name,
canon_ace ace_list 
) [static]

posix_acls.c594 行で定義されています。

参照先 dbgtext()canon_ace::nextprint_canon_ace().

参照元 unpack_canon_ace().

00595 {
00596         int count = 0;
00597 
00598         if( DEBUGLVL( 10 )) {
00599                 dbgtext( "print_canon_ace_list: %s\n", name );
00600                 for (;ace_list; ace_list = ace_list->next, count++)
00601                         print_canon_ace(ace_list, count );
00602         }
00603 }

static mode_t convert_permset_to_mode_t ( connection_struct conn,
SMB_ACL_PERMSET_T  permset 
) [static]

posix_acls.c609 行で定義されています。

参照元 canonicalise_acl().

00610 {
00611         mode_t ret = 0;
00612 
00613         ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRUSR : 0);
00614         ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWUSR : 0);
00615         ret |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0);
00616 
00617         return ret;
00618 }

static mode_t unix_perms_to_acl_perms ( mode_t  mode,
int  r_mask,
int  w_mask,
int  x_mask 
) [static]

posix_acls.c624 行で定義されています。

参照元 apply_default_perms()chmod_acl_internals().

00625 {
00626         mode_t ret = 0;
00627 
00628         if (mode & r_mask)
00629                 ret |= S_IRUSR;
00630         if (mode & w_mask)
00631                 ret |= S_IWUSR;
00632         if (mode & x_mask)
00633                 ret |= S_IXUSR;
00634 
00635         return ret;
00636 }

static int map_acl_perms_to_permset ( connection_struct conn,
mode_t  mode,
SMB_ACL_PERMSET_T p_permset 
) [static]

posix_acls.c643 行で定義されています。

参照元 chmod_acl_internals().

00644 {
00645         if (SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, *p_permset) ==  -1)
00646                 return -1;
00647         if (mode & S_IRUSR) {
00648                 if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1)
00649                         return -1;
00650         }
00651         if (mode & S_IWUSR) {
00652                 if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1)
00653                         return -1;
00654         }
00655         if (mode & S_IXUSR) {
00656                 if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1)
00657                         return -1;
00658         }
00659         return 0;
00660 }

static void create_file_sids ( SMB_STRUCT_STAT *  psbuf,
DOM_SID powner_sid,
DOM_SID pgroup_sid 
) [static]

posix_acls.c666 行で定義されています。

参照先 gid_to_sid()uid_to_sid().

参照元 get_nt_acl()set_nt_acl().

00667 {
00668         uid_to_sid( powner_sid, psbuf->st_uid );
00669         gid_to_sid( pgroup_sid, psbuf->st_gid );
00670 }

static BOOL identity_in_ace_equal ( canon_ace ace1,
canon_ace ace2 
) [static]

posix_acls.c676 行で定義されています。

参照先 posix_id::gidGID_ACEcanon_ace::owner_typesid_equal()canon_ace::trusteeposix_id::uidUID_ACEcanon_ace::unix_ug.

参照元 merge_aces().

00677 {
00678         if (sid_equal(&ace1->trustee, &ace2->trustee)) {
00679                 return True;
00680         }
00681         if (ace1->owner_type == ace2->owner_type) {
00682                 if (ace1->owner_type == UID_ACE &&
00683                                 ace1->unix_ug.uid == ace2->unix_ug.uid) {
00684                         return True;
00685                 } else if (ace1->owner_type == GID_ACE &&
00686                                 ace1->unix_ug.gid == ace2->unix_ug.gid) {
00687                         return True;
00688                 }
00689         }
00690         return False;
00691 }

static void merge_aces ( canon_ace **  pp_list_head  )  [static]

posix_acls.c699 行で定義されています。

参照先 canon_ace::attrdbgtext()identity_in_ace_equal()canon_ace::nextcanon_ace::permsprint_canon_ace().

参照元 unpack_canon_ace().

00700 {
00701         canon_ace *list_head = *pp_list_head;
00702         canon_ace *curr_ace_outer;
00703         canon_ace *curr_ace_outer_next;
00704 
00705         /*
00706          * First, merge allow entries with identical SIDs, and deny entries
00707          * with identical SIDs.
00708          */
00709 
00710         for (curr_ace_outer = list_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) {
00711                 canon_ace *curr_ace;
00712                 canon_ace *curr_ace_next;
00713 
00714                 curr_ace_outer_next = curr_ace_outer->next; /* Save the link in case we delete. */
00715 
00716                 for (curr_ace = curr_ace_outer->next; curr_ace; curr_ace = curr_ace_next) {
00717 
00718                         curr_ace_next = curr_ace->next; /* Save the link in case of delete. */
00719 
00720                         if (identity_in_ace_equal(curr_ace, curr_ace_outer) &&
00721                                 (curr_ace->attr == curr_ace_outer->attr)) {
00722 
00723                                 if( DEBUGLVL( 10 )) {
00724                                         dbgtext("merge_aces: Merging ACE's\n");
00725                                         print_canon_ace( curr_ace_outer, 0);
00726                                         print_canon_ace( curr_ace, 0);
00727                                 }
00728 
00729                                 /* Merge two allow or two deny ACE's. */
00730 
00731                                 curr_ace_outer->perms |= curr_ace->perms;
00732                                 DLIST_REMOVE(list_head, curr_ace);
00733                                 SAFE_FREE(curr_ace);
00734                                 curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */
00735                         }
00736                 }
00737         }
00738 
00739         /*
00740          * Now go through and mask off allow permissions with deny permissions.
00741          * We can delete either the allow or deny here as we know that each SID
00742          * appears only once in the list.
00743          */
00744 
00745         for (curr_ace_outer = list_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) {
00746                 canon_ace *curr_ace;
00747                 canon_ace *curr_ace_next;
00748 
00749                 curr_ace_outer_next = curr_ace_outer->next; /* Save the link in case we delete. */
00750 
00751                 for (curr_ace = curr_ace_outer->next; curr_ace; curr_ace = curr_ace_next) {
00752 
00753                         curr_ace_next = curr_ace->next; /* Save the link in case of delete. */
00754 
00755                         /*
00756                          * Subtract ACE's with different entries. Due to the ordering constraints
00757                          * we've put on the ACL, we know the deny must be the first one.
00758                          */
00759 
00760                         if (identity_in_ace_equal(curr_ace, curr_ace_outer) &&
00761                                 (curr_ace_outer->attr == DENY_ACE) && (curr_ace->attr == ALLOW_ACE)) {
00762 
00763                                 if( DEBUGLVL( 10 )) {
00764                                         dbgtext("merge_aces: Masking ACE's\n");
00765                                         print_canon_ace( curr_ace_outer, 0);
00766                                         print_canon_ace( curr_ace, 0);
00767                                 }
00768 
00769                                 curr_ace->perms &= ~curr_ace_outer->perms;
00770 
00771                                 if (curr_ace->perms == 0) {
00772 
00773                                         /*
00774                                          * The deny overrides the allow. Remove the allow.
00775                                          */
00776 
00777                                         DLIST_REMOVE(list_head, curr_ace);
00778                                         SAFE_FREE(curr_ace);
00779                                         curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */
00780 
00781                                 } else {
00782 
00783                                         /*
00784                                          * Even after removing permissions, there
00785                                          * are still allow permissions - delete the deny.
00786                                          * It is safe to delete the deny here,
00787                                          * as we are guarenteed by the deny first
00788                                          * ordering that all the deny entries for
00789                                          * this SID have already been merged into one
00790                                          * before we can get to an allow ace.
00791                                          */
00792 
00793                                         DLIST_REMOVE(list_head, curr_ace_outer);
00794                                         SAFE_FREE(curr_ace_outer);
00795                                         break;
00796                                 }
00797                         }
00798 
00799                 } /* end for curr_ace */
00800         } /* end for curr_ace_outer */
00801 
00802         /* We may have modified the list. */
00803 
00804         *pp_list_head = list_head;
00805 }

static BOOL nt4_compatible_acls ( void   )  [static]

posix_acls.c811 行で定義されています。

参照先 ACL_COMPAT_AUTOACL_COMPAT_WINNTget_remote_arch()ra_typeRA_WINNT.

参照元 create_canon_ace_lists()get_nt_acl()map_canon_ace_perms().

00812 {
00813         int compat = lp_acl_compatibility();
00814 
00815         if (compat == ACL_COMPAT_AUTO) {
00816                 enum remote_arch_types ra_type = get_remote_arch();
00817 
00818                 /* Automatically adapt to client */
00819                 return (ra_type <= RA_WINNT);
00820         } else
00821                 return (compat == ACL_COMPAT_WINNT);
00822 }

static SEC_ACCESS map_canon_ace_perms ( int  snum,
int *  pacl_type,
mode_t  perms,
BOOL  directory_ace 
) [static]

posix_acls.c831 行で定義されています。

参照先 init_sec_access()nt4_compatible_acls()SEC_ACE_TYPE_ACCESS_ALLOWED.

参照元 get_nt_acl().

00835 {
00836         SEC_ACCESS sa;
00837         uint32 nt_mask = 0;
00838 
00839         *pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
00840 
00841         if (lp_acl_map_full_control(snum) && ((perms & ALL_ACE_PERMS) == ALL_ACE_PERMS)) {
00842                 if (directory_ace) {
00843                         nt_mask = UNIX_DIRECTORY_ACCESS_RWX;
00844                 } else {
00845                         nt_mask = UNIX_ACCESS_RWX;
00846                 }
00847         } else if ((perms & ALL_ACE_PERMS) == (mode_t)0) {
00848                 /*
00849                  * Windows NT refuses to display ACEs with no permissions in them (but
00850                  * they are perfectly legal with Windows 2000). If the ACE has empty
00851                  * permissions we cannot use 0, so we use the otherwise unused
00852                  * WRITE_OWNER permission, which we ignore when we set an ACL.
00853                  * We abstract this into a #define of UNIX_ACCESS_NONE to allow this
00854                  * to be changed in the future.
00855                  */
00856 
00857                 if (nt4_compatible_acls())
00858                         nt_mask = UNIX_ACCESS_NONE;
00859                 else
00860                         nt_mask = 0;
00861         } else {
00862                 if (directory_ace) {
00863                         nt_mask |= ((perms & S_IRUSR) ? UNIX_DIRECTORY_ACCESS_R : 0 );
00864                         nt_mask |= ((perms & S_IWUSR) ? UNIX_DIRECTORY_ACCESS_W : 0 );
00865                         nt_mask |= ((perms & S_IXUSR) ? UNIX_DIRECTORY_ACCESS_X : 0 );
00866                 } else {
00867                         nt_mask |= ((perms & S_IRUSR) ? UNIX_ACCESS_R : 0 );
00868                         nt_mask |= ((perms & S_IWUSR) ? UNIX_ACCESS_W : 0 );
00869                         nt_mask |= ((perms & S_IXUSR) ? UNIX_ACCESS_X : 0 );
00870                 }
00871         }
00872 
00873         DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n",
00874                         (unsigned int)perms, (unsigned int)nt_mask ));
00875 
00876         init_sec_access(&sa,nt_mask);
00877         return sa;
00878 }

static mode_t map_nt_perms ( uint32 *  mask,
int  type 
) [static]

posix_acls.c888 行で定義されています。

参照先 mode.

00889 {
00890         mode_t mode = 0;
00891 
00892         switch(type) {
00893         case S_IRUSR:
00894                 if((*mask) & GENERIC_ALL_ACCESS)
00895                         mode = S_IRUSR|S_IWUSR|S_IXUSR;
00896                 else {
00897                         mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0;
00898                         mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0;
00899                         mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0;
00900                 }
00901                 break;
00902         case S_IRGRP:
00903                 if((*mask) & GENERIC_ALL_ACCESS)
00904                         mode = S_IRGRP|S_IWGRP|S_IXGRP;
00905                 else {
00906                         mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0;
00907                         mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0;
00908                         mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0;
00909                 }
00910                 break;
00911         case S_IROTH:
00912                 if((*mask) & GENERIC_ALL_ACCESS)
00913                         mode = S_IROTH|S_IWOTH|S_IXOTH;
00914                 else {
00915                         mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0;
00916                         mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0;
00917                         mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0;
00918                 }
00919                 break;
00920         }
00921 
00922         return mode;
00923 }

BOOL unpack_nt_owners ( int  snum,
uid_t *  puser,
gid_t *  pgrp,
uint32  security_info_sent,
SEC_DESC psd 
)

posix_acls.c929 行で定義されています。

参照先 current_user_unix_token::gidsecurity_descriptor_info::group_sidsecurity_descriptor_info::owner_sidsid_copy()sid_string_static()sid_to_gid()sid_to_uid()_unix_token::uidcurrent_user::ut.

00930 {
00931         DOM_SID owner_sid;
00932         DOM_SID grp_sid;
00933 
00934         *puser = (uid_t)-1;
00935         *pgrp = (gid_t)-1;
00936 
00937         if(security_info_sent == 0) {
00938                 DEBUG(0,("unpack_nt_owners: no security info sent !\n"));
00939                 return True;
00940         }
00941 
00942         /*
00943          * Validate the owner and group SID's.
00944          */
00945 
00946         memset(&owner_sid, '\0', sizeof(owner_sid));
00947         memset(&grp_sid, '\0', sizeof(grp_sid));
00948 
00949         DEBUG(5,("unpack_nt_owners: validating owner_sids.\n"));
00950 
00951         /*
00952          * Don't immediately fail if the owner sid cannot be validated.
00953          * This may be a group chown only set.
00954          */
00955 
00956         if (security_info_sent & OWNER_SECURITY_INFORMATION) {
00957                 sid_copy(&owner_sid, psd->owner_sid);
00958                 if (!sid_to_uid(&owner_sid, puser)) {
00959                         if (lp_force_unknown_acl_user(snum)) {
00960                                 /* this allows take ownership to work
00961                                  * reasonably */
00962                                 *puser = current_user.ut.uid;
00963                         } else {
00964                                 DEBUG(3,("unpack_nt_owners: unable to validate"
00965                                          " owner sid for %s\n",
00966                                          sid_string_static(&owner_sid)));
00967                                 return False;
00968                         }
00969                 }
00970         }
00971 
00972         /*
00973          * Don't immediately fail if the group sid cannot be validated.
00974          * This may be an owner chown only set.
00975          */
00976 
00977         if (security_info_sent & GROUP_SECURITY_INFORMATION) {
00978                 sid_copy(&grp_sid, psd->group_sid);
00979                 if (!sid_to_gid( &grp_sid, pgrp)) {
00980                         if (lp_force_unknown_acl_user(snum)) {
00981                                 /* this allows take group ownership to work
00982                                  * reasonably */
00983                                 *pgrp = current_user.ut.gid;
00984                         } else {
00985                                 DEBUG(3,("unpack_nt_owners: unable to validate"
00986                                          " group sid.\n"));
00987                                 return False;
00988                         }
00989                 }
00990         }
00991 
00992         DEBUG(5,("unpack_nt_owners: owner_sids validated.\n"));
00993 
00994         return True;
00995 }

static void apply_default_perms ( files_struct fsp,
canon_ace pace,
mode_t  type 
) [static]

posix_acls.c1001 行で定義されています。

参照先 files_struct::connfiles_struct::is_directorycanon_ace::permsunix_perms_to_acl_perms().

参照元 ensure_canon_entry_valid().

01002 {
01003         int snum = SNUM(fsp->conn);
01004         mode_t and_bits = (mode_t)0;
01005         mode_t or_bits = (mode_t)0;
01006 
01007         /* Get the initial bits to apply. */
01008 
01009         if (fsp->is_directory) {
01010                 and_bits = lp_dir_security_mask(snum);
01011                 or_bits = lp_force_dir_security_mode(snum);
01012         } else {
01013                 and_bits = lp_security_mask(snum);
01014                 or_bits = lp_force_security_mode(snum);
01015         }
01016 
01017         /* Now bounce them into the S_USR space. */     
01018         switch(type) {
01019         case S_IRUSR:
01020                 /* Ensure owner has read access. */
01021                 pace->perms |= S_IRUSR;
01022                 if (fsp->is_directory)
01023                         pace->perms |= (S_IWUSR|S_IXUSR);
01024                 and_bits = unix_perms_to_acl_perms(and_bits, S_IRUSR, S_IWUSR, S_IXUSR);
01025                 or_bits = unix_perms_to_acl_perms(or_bits, S_IRUSR, S_IWUSR, S_IXUSR);
01026                 break;
01027         case S_IRGRP:
01028                 and_bits = unix_perms_to_acl_perms(and_bits, S_IRGRP, S_IWGRP, S_IXGRP);
01029                 or_bits = unix_perms_to_acl_perms(or_bits, S_IRGRP, S_IWGRP, S_IXGRP);
01030                 break;
01031         case S_IROTH:
01032                 and_bits = unix_perms_to_acl_perms(and_bits, S_IROTH, S_IWOTH, S_IXOTH);
01033                 or_bits = unix_perms_to_acl_perms(or_bits, S_IROTH, S_IWOTH, S_IXOTH);
01034                 break;
01035         }
01036 
01037         pace->perms = ((pace->perms & and_bits)|or_bits);
01038 }

static BOOL uid_entry_in_group ( canon_ace uid_ace,
canon_ace group_ace 
) [static]

posix_acls.c1045 行で定義されています。

参照先 current_user_unix_token::gidposix_id::gidglobal_sid_Worldsid_equal()canon_ace::trustee_unix_token::uidposix_id::uiduidtoname()canon_ace::unix_uguser_in_group_sid()current_user::ut.

01046 {
01047         fstring u_name;
01048 
01049         /* "Everyone" always matches every uid. */
01050 
01051         if (sid_equal(&group_ace->trustee, &global_sid_World))
01052                 return True;
01053 
01054         /* Assume that the current user is in the current group (force group) */
01055 
01056         if (uid_ace->unix_ug.uid == current_user.ut.uid && group_ace->unix_ug.gid == current_user.ut.gid)
01057                 return True;
01058 
01059         fstrcpy(u_name, uidtoname(uid_ace->unix_ug.uid));
01060         return user_in_group_sid(u_name, &group_ace->trustee);
01061 }

static BOOL ensure_canon_entry_valid ( canon_ace **  pp_ace,
files_struct fsp,
const DOM_SID pfile_owner_sid,
const DOM_SID pfile_grp_sid,
SMB_STRUCT_STAT *  pst,
BOOL  setting_acl 
) [static]

posix_acls.c1073 行で定義されています。

参照先 apply_default_perms()got_usercanon_ace::nextSMB_ACL_GROUP_OBJSMB_ACL_USER_OBJcanon_ace::type.

参照元 canonicalise_acl()unpack_canon_ace().

01079 {
01080         canon_ace *pace;
01081         BOOL got_user = False;
01082         BOOL got_grp = False;
01083         BOOL got_other = False;
01084         canon_ace *pace_other = NULL;
01085 
01086         for (pace = *pp_ace; pace; pace = pace->next) {
01087                 if (pace->type == SMB_ACL_USER_OBJ) {
01088 
01089                         if (setting_acl)
01090                                 apply_default_perms(fsp, pace, S_IRUSR);
01091                         got_user = True;
01092 
01093                 } else if (pace->type == SMB_ACL_GROUP_OBJ) {
01094 
01095                         /*
01096                          * Ensure create mask/force create mode is respected on set.
01097                          */
01098 
01099                         if (setting_acl)
01100                                 apply_default_perms(fsp, pace, S_IRGRP);
01101                         got_grp = True;
01102 
01103                 } else if (pace->type == SMB_ACL_OTHER) {
01104 
01105                         /*
01106                          * Ensure create mask/force create mode is respected on set.
01107                          */
01108 
01109                         if (setting_acl)
01110                                 apply_default_perms(fsp, pace, S_IROTH);
01111                         got_other = True;
01112                         pace_other = pace;
01113                 }
01114         }
01115 
01116         if (!got_user) {
01117                 if ((pace = SMB_MALLOC_P(canon_ace)) == NULL) {
01118                         DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
01119                         return False;
01120                 }
01121 
01122                 ZERO_STRUCTP(pace);
01123                 pace->type = SMB_ACL_USER_OBJ;
01124                 pace->owner_type = UID_ACE;
01125                 pace->unix_ug.uid = pst->st_uid;
01126                 pace->trustee = *pfile_owner_sid;
01127                 pace->attr = ALLOW_ACE;
01128 
01129                 if (setting_acl) {
01130                         /* See if the owning user is in any of the other groups in
01131                            the ACE. If so, OR in the permissions from that group. */
01132 
01133                         BOOL group_matched = False;
01134                         canon_ace *pace_iter;
01135 
01136                         for (pace_iter = *pp_ace; pace_iter; pace_iter = pace_iter->next) {
01137                                 if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) {
01138                                         if (uid_entry_in_group(pace, pace_iter)) {
01139                                                 pace->perms |= pace_iter->perms;
01140                                                 group_matched = True;
01141                                         }
01142                                 }
01143                         }
01144 
01145                         /* If we only got an "everyone" perm, just use that. */
01146                         if (!group_matched) {
01147                                 if (got_other)
01148                                         pace->perms = pace_other->perms;
01149                                 else
01150                                         pace->perms = 0;
01151                         }
01152 
01153                         apply_default_perms(fsp, pace, S_IRUSR);
01154                 } else {
01155                         pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR);
01156                 }
01157 
01158                 DLIST_ADD(*pp_ace, pace);
01159         }
01160 
01161         if (!got_grp) {
01162                 if ((pace = SMB_MALLOC_P(canon_ace)) == NULL) {
01163                         DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
01164                         return False;
01165                 }
01166 
01167                 ZERO_STRUCTP(pace);
01168                 pace->type = SMB_ACL_GROUP_OBJ;
01169                 pace->owner_type = GID_ACE;
01170                 pace->unix_ug.uid = pst->st_gid;
01171                 pace->trustee = *pfile_grp_sid;
01172                 pace->attr = ALLOW_ACE;
01173                 if (setting_acl) {
01174                         /* If we only got an "everyone" perm, just use that. */
01175                         if (got_other)
01176                                 pace->perms = pace_other->perms;
01177                         else
01178                                 pace->perms = 0;
01179                         apply_default_perms(fsp, pace, S_IRGRP);
01180                 } else {
01181                         pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP);
01182                 }
01183 
01184                 DLIST_ADD(*pp_ace, pace);
01185         }
01186 
01187         if (!got_other) {
01188                 if ((pace = SMB_MALLOC_P(canon_ace)) == NULL) {
01189                         DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
01190                         return False;
01191                 }
01192 
01193                 ZERO_STRUCTP(pace);
01194                 pace->type = SMB_ACL_OTHER;
01195                 pace->owner_type = WORLD_ACE;
01196                 pace->unix_ug.world = -1;
01197                 pace->trustee = global_sid_World;
01198                 pace->attr = ALLOW_ACE;
01199                 if (setting_acl) {
01200                         pace->perms = 0;
01201                         apply_default_perms(fsp, pace, S_IROTH);
01202                 } else
01203                         pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH);
01204 
01205                 DLIST_ADD(*pp_ace, pace);
01206         }
01207 
01208         return True;
01209 }

static void check_owning_objs ( canon_ace ace,
DOM_SID pfile_owner_sid,
DOM_SID pfile_grp_sid 
) [static]

posix_acls.c1217 行で定義されています。

参照先 count_canon_ace_list()GID_ACEcanon_ace::nextsid_equal()SMB_ACL_GROUP_OBJSMB_ACL_USER_OBJUID_ACE.

01218 {
01219         BOOL got_user_obj, got_group_obj;
01220         canon_ace *current_ace;
01221         int i, entries;
01222 
01223         entries = count_canon_ace_list(ace);
01224         got_user_obj = False;
01225         got_group_obj = False;
01226 
01227         for (i=0, current_ace = ace; i < entries; i++, current_ace = current_ace->next) {
01228                 if (current_ace->type == SMB_ACL_USER_OBJ)
01229                         got_user_obj = True;
01230                 else if (current_ace->type == SMB_ACL_GROUP_OBJ)
01231                         got_group_obj = True;
01232         }
01233         if (got_user_obj && got_group_obj) {
01234                 DEBUG(10,("check_owning_objs: ACL had owning user/group entries.\n"));
01235                 return;
01236         }
01237 
01238         for (i=0, current_ace = ace; i < entries; i++, current_ace = current_ace->next) {
01239                 if (!got_user_obj && current_ace->owner_type == UID_ACE &&
01240                                 sid_equal(&current_ace->trustee, pfile_owner_sid)) {
01241                         current_ace->type = SMB_ACL_USER_OBJ;
01242                         got_user_obj = True;
01243                 }
01244                 if (!got_group_obj && current_ace->owner_type == GID_ACE &&
01245                                 sid_equal(&current_ace->trustee, pfile_grp_sid)) {
01246                         current_ace->type = SMB_ACL_GROUP_OBJ;
01247                         got_group_obj = True;
01248                 }
01249         }
01250         if (!got_user_obj)
01251                 DEBUG(10,("check_owning_objs: ACL is missing an owner entry.\n"));
01252         if (!got_group_obj)
01253                 DEBUG(10,("check_owning_objs: ACL is missing an owning group entry.\n"));
01254 }

static BOOL create_canon_ace_lists ( files_struct fsp,
SMB_STRUCT_STAT *  pst,
DOM_SID pfile_owner_sid,
DOM_SID pfile_grp_sid,
canon_ace **  ppfile_ace,
canon_ace **  ppdir_ace,
SEC_ACL dacl 
) [static]

posix_acls.c1260 行で定義されています。

参照先 security_acl_info::acesfile_generic_mappingfiles_struct::is_directorynt4_compatible_acls()security_acl_info::num_acesse_map_generic()SEC_ACE_TYPE_ACCESS_ALLOWEDSEC_ACE_TYPE_ACCESS_DENIED.

参照元 unpack_canon_ace().

01265 {
01266         BOOL all_aces_are_inherit_only = (fsp->is_directory ? True : False);
01267         canon_ace *file_ace = NULL;
01268         canon_ace *dir_ace = NULL;
01269         canon_ace *current_ace = NULL;
01270         BOOL got_dir_allow = False;
01271         BOOL got_file_allow = False;
01272         int i, j;
01273 
01274         *ppfile_ace = NULL;
01275         *ppdir_ace = NULL;
01276 
01277         /*
01278          * Convert the incoming ACL into a more regular form.
01279          */
01280 
01281         for(i = 0; i < dacl->num_aces; i++) {
01282                 SEC_ACE *psa = &dacl->aces[i];
01283 
01284                 if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) && (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) {
01285                         DEBUG(3,("create_canon_ace_lists: unable to set anything but an ALLOW or DENY ACE.\n"));
01286                         return False;
01287                 }
01288 
01289                 if (nt4_compatible_acls()) {
01290                         /*
01291                          * The security mask may be UNIX_ACCESS_NONE which should map into
01292                          * no permissions (we overload the WRITE_OWNER bit for this) or it
01293                          * should be one of the ALL/EXECUTE/READ/WRITE bits. Arrange for this
01294                          * to be so. Any other bits override the UNIX_ACCESS_NONE bit.
01295                          */
01296 
01297                         /*
01298                          * Convert GENERIC bits to specific bits.
01299                          */
01300  
01301                         se_map_generic(&psa->access_mask, &file_generic_mapping);
01302 
01303                         psa->access_mask &= (UNIX_ACCESS_NONE|FILE_ALL_ACCESS);
01304 
01305                         if(psa->access_mask != UNIX_ACCESS_NONE)
01306                                 psa->access_mask &= ~UNIX_ACCESS_NONE;
01307                 }
01308         }
01309 
01310         /*
01311          * Deal with the fact that NT 4.x re-writes the canonical format
01312          * that we return for default ACLs. If a directory ACE is identical
01313          * to a inherited directory ACE then NT changes the bits so that the
01314          * first ACE is set to OI|IO and the second ACE for this SID is set
01315          * to CI. We need to repair this. JRA.
01316          */
01317 
01318         for(i = 0; i < dacl->num_aces; i++) {
01319                 SEC_ACE *psa1 = &dacl->aces[i];
01320 
01321                 for (j = i + 1; j < dacl->num_aces; j++) {
01322                         SEC_ACE *psa2 = &dacl->aces[j];
01323 
01324                         if (psa1->access_mask != psa2->access_mask)
01325                                 continue;
01326 
01327                         if (!sid_equal(&psa1->trustee, &psa2->trustee))
01328                                 continue;
01329 
01330                         /*
01331                          * Ok - permission bits and SIDs are equal.
01332                          * Check if flags were re-written.
01333                          */
01334 
01335                         if (psa1->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
01336 
01337                                 psa1->flags |= (psa2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT));
01338                                 psa2->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT);
01339 
01340                         } else if (psa2->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
01341 
01342                                 psa2->flags |= (psa1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT));
01343                                 psa1->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT);
01344 
01345                         }
01346                 }
01347         }
01348 
01349         for(i = 0; i < dacl->num_aces; i++) {
01350                 SEC_ACE *psa = &dacl->aces[i];
01351 
01352                 /*
01353                  * Create a cannon_ace entry representing this NT DACL ACE.
01354                  */
01355 
01356                 if ((current_ace = SMB_MALLOC_P(canon_ace)) == NULL) {
01357                         free_canon_ace_list(file_ace);
01358                         free_canon_ace_list(dir_ace);
01359                         DEBUG(0,("create_canon_ace_lists: malloc fail.\n"));
01360                         return False;
01361                 }
01362 
01363                 ZERO_STRUCTP(current_ace);
01364 
01365                 sid_copy(&current_ace->trustee, &psa->trustee);
01366 
01367                 /*
01368                  * Try and work out if the SID is a user or group
01369                  * as we need to flag these differently for POSIX.
01370                  * Note what kind of a POSIX ACL this should map to.
01371                  */
01372 
01373                 if( sid_equal(&current_ace->trustee, &global_sid_World)) {
01374                         current_ace->owner_type = WORLD_ACE;
01375                         current_ace->unix_ug.world = -1;
01376                         current_ace->type = SMB_ACL_OTHER;
01377                 } else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Owner)) {
01378                         current_ace->owner_type = UID_ACE;
01379                         current_ace->unix_ug.uid = pst->st_uid;
01380                         current_ace->type = SMB_ACL_USER_OBJ;
01381 
01382                         /*
01383                          * The Creator Owner entry only specifies inheritable permissions,
01384                          * never access permissions. WinNT doesn't always set the ACE to
01385                          *INHERIT_ONLY, though.
01386                          */
01387 
01388                         if (nt4_compatible_acls())
01389                                 psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
01390                 } else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Group)) {
01391                         current_ace->owner_type = GID_ACE;
01392                         current_ace->unix_ug.gid = pst->st_gid;
01393                         current_ace->type = SMB_ACL_GROUP_OBJ;
01394 
01395                         /*
01396                          * The Creator Group entry only specifies inheritable permissions,
01397                          * never access permissions. WinNT doesn't always set the ACE to
01398                          *INHERIT_ONLY, though.
01399                          */
01400                         if (nt4_compatible_acls())
01401                                 psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
01402 
01403                 } else if (sid_to_uid( &current_ace->trustee, &current_ace->unix_ug.uid)) {
01404                         current_ace->owner_type = UID_ACE;
01405                         /* If it's the owning user, this is a user_obj, not
01406                          * a user. */
01407                         if (current_ace->unix_ug.uid == pst->st_uid) {
01408                                 current_ace->type = SMB_ACL_USER_OBJ;
01409                         } else {
01410                                 current_ace->type = SMB_ACL_USER;
01411                         }
01412                 } else if (sid_to_gid( &current_ace->trustee, &current_ace->unix_ug.gid)) {
01413                         current_ace->owner_type = GID_ACE;
01414                         /* If it's the primary group, this is a group_obj, not
01415                          * a group. */
01416                         if (current_ace->unix_ug.gid == pst->st_gid) {
01417                                 current_ace->type = SMB_ACL_GROUP_OBJ;
01418                         } else {
01419                                 current_ace->type = SMB_ACL_GROUP;
01420                         }
01421                 } else {
01422                         fstring str;
01423 
01424                         /*
01425                          * Silently ignore map failures in non-mappable SIDs (NT Authority, BUILTIN etc).
01426                          */
01427 
01428                         if (non_mappable_sid(&psa->trustee)) {
01429                                 DEBUG(10,("create_canon_ace_lists: ignoring non-mappable SID %s\n",
01430                                         sid_to_string(str, &psa->trustee) ));
01431                                 SAFE_FREE(current_ace);
01432                                 continue;
01433                         }
01434 
01435                         free_canon_ace_list(file_ace);
01436                         free_canon_ace_list(dir_ace);
01437                         DEBUG(0,("create_canon_ace_lists: unable to map SID %s to uid or gid.\n",
01438                                 sid_to_string(str, &current_ace->trustee) ));
01439                         SAFE_FREE(current_ace);
01440                         return False;
01441                 }
01442 
01443                 /*
01444                  * Map the given NT permissions into a UNIX mode_t containing only
01445                  * S_I(R|W|X)USR bits.
01446                  */
01447 
01448                 current_ace->perms |= map_nt_perms( &psa->access_mask, S_IRUSR);
01449                 current_ace->attr = (psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED) ? ALLOW_ACE : DENY_ACE;
01450                 current_ace->inherited = ((psa->flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False);
01451 
01452                 /*
01453                  * Now add the created ace to either the file list, the directory
01454                  * list, or both. We *MUST* preserve the order here (hence we use
01455                  * DLIST_ADD_END) as NT ACLs are order dependent.
01456                  */
01457 
01458                 if (fsp->is_directory) {
01459 
01460                         /*
01461                          * We can only add to the default POSIX ACE list if the ACE is
01462                          * designed to be inherited by both files and directories.
01463                          */
01464 
01465                         if ((psa->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT)) ==
01466                                 (SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT)) {
01467 
01468                                 DLIST_ADD_END(dir_ace, current_ace, canon_ace *);
01469 
01470                                 /*
01471                                  * Note if this was an allow ace. We can't process
01472                                  * any further deny ace's after this.
01473                                  */
01474 
01475                                 if (current_ace->attr == ALLOW_ACE)
01476                                         got_dir_allow = True;
01477 
01478                                 if ((current_ace->attr == DENY_ACE) && got_dir_allow) {
01479                                         DEBUG(0,("create_canon_ace_lists: malformed ACL in inheritable ACL ! \
01480 Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
01481                                         free_canon_ace_list(file_ace);
01482                                         free_canon_ace_list(dir_ace);
01483                                         return False;
01484                                 }       
01485 
01486                                 if( DEBUGLVL( 10 )) {
01487                                         dbgtext("create_canon_ace_lists: adding dir ACL:\n");
01488                                         print_canon_ace( current_ace, 0);
01489                                 }
01490 
01491                                 /*
01492                                  * If this is not an inherit only ACE we need to add a duplicate
01493                                  * to the file acl.
01494                                  */
01495 
01496                                 if (!(psa->flags & SEC_ACE_FLAG_INHERIT_ONLY)) {
01497                                         canon_ace *dup_ace = dup_canon_ace(current_ace);
01498 
01499                                         if (!dup_ace) {
01500                                                 DEBUG(0,("create_canon_ace_lists: malloc fail !\n"));
01501                                                 free_canon_ace_list(file_ace);
01502                                                 free_canon_ace_list(dir_ace);
01503                                                 return False;
01504                                         }
01505 
01506                                         /*
01507                                          * We must not free current_ace here as its
01508                                          * pointer is now owned by the dir_ace list.
01509                                          */
01510                                         current_ace = dup_ace;
01511                                 } else {
01512                                         /*
01513                                          * We must not free current_ace here as its
01514                                          * pointer is now owned by the dir_ace list.
01515                                          */
01516                                         current_ace = NULL;
01517                                 }
01518                         }
01519                 }
01520 
01521                 /*
01522                  * Only add to the file ACL if not inherit only.
01523                  */
01524 
01525                 if (current_ace && !(psa->flags & SEC_ACE_FLAG_INHERIT_ONLY)) {
01526                         DLIST_ADD_END(file_ace, current_ace, canon_ace *);
01527 
01528                         /*
01529                          * Note if this was an allow ace. We can't process
01530                          * any further deny ace's after this.
01531                          */
01532 
01533                         if (current_ace->attr == ALLOW_ACE)
01534                                 got_file_allow = True;
01535 
01536                         if ((current_ace->attr == DENY_ACE) && got_file_allow) {
01537                                 DEBUG(0,("create_canon_ace_lists: malformed ACL in file ACL ! \
01538 Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
01539                                 free_canon_ace_list(file_ace);
01540                                 free_canon_ace_list(dir_ace);
01541                                 return False;
01542                         }       
01543 
01544                         if( DEBUGLVL( 10 )) {
01545                                 dbgtext("create_canon_ace_lists: adding file ACL:\n");
01546                                 print_canon_ace( current_ace, 0);
01547                         }
01548                         all_aces_are_inherit_only = False;
01549                         /*
01550                          * We must not free current_ace here as its
01551                          * pointer is now owned by the file_ace list.
01552                          */
01553                         current_ace = NULL;
01554                 }
01555 
01556                 /*
01557                  * Free if ACE was not added.
01558                  */
01559 
01560                 SAFE_FREE(current_ace);
01561         }
01562 
01563         if (fsp->is_directory && all_aces_are_inherit_only) {
01564                 /*
01565                  * Windows 2000 is doing one of these weird 'inherit acl'
01566                  * traverses to conserve NTFS ACL resources. Just pretend
01567                  * there was no DACL sent. JRA.
01568                  */
01569 
01570                 DEBUG(10,("create_canon_ace_lists: Win2k inherit acl traverse. Ignoring DACL.\n"));
01571                 free_canon_ace_list(file_ace);
01572                 free_canon_ace_list(dir_ace);
01573                 file_ace = NULL;
01574                 dir_ace = NULL;
01575         } else {
01576                 /*
01577                  * Check if we have SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ entries in each
01578                  * ACL. If we don't have them, check if any SMB_ACL_USER/SMB_ACL_GROUP
01579                  * entries can be converted to *_OBJ. Usually we will already have these
01580                  * entries in the Default ACL, and the Access ACL will not have them.
01581                  */
01582                 if (file_ace) {
01583                         check_owning_objs(file_ace, pfile_owner_sid, pfile_grp_sid);
01584                 }
01585                 if (dir_ace) {
01586                         check_owning_objs(dir_ace, pfile_owner_sid, pfile_grp_sid);
01587                 }
01588         }
01589 
01590         *ppfile_ace = file_ace;
01591         *ppdir_ace = dir_ace;
01592 
01593         return True;
01594 }

static void process_deny_list ( canon_ace **  pp_ace_list  )  [static]

posix_acls.c1700 行で定義されています。

参照先 canon_ace::attrDENY_ACEfree_canon_ace_list()global_sid_Worldcanon_ace::nextcanon_ace::owner_typecanon_ace::permscanon_ace::prevsid_equal()canon_ace::trusteeWORLD_ACE.

参照元 unpack_canon_ace().

01701 {
01702         canon_ace *ace_list = *pp_ace_list;
01703         canon_ace *curr_ace = NULL;
01704         canon_ace *curr_ace_next = NULL;
01705 
01706         /* Pass 1 above - look for an Everyone, deny entry. */
01707 
01708         for (curr_ace = ace_list; curr_ace; curr_ace = curr_ace_next) {
01709                 canon_ace *allow_ace_p;
01710 
01711                 curr_ace_next = curr_ace->next; /* So we can't lose the link. */
01712 
01713                 if (curr_ace->attr != DENY_ACE)
01714                         continue;
01715 
01716                 if (curr_ace->perms == (mode_t)0) {
01717 
01718                         /* Deny nothing entry - delete. */
01719 
01720                         DLIST_REMOVE(ace_list, curr_ace);
01721                         continue;
01722                 }
01723 
01724                 if (!sid_equal(&curr_ace->trustee, &global_sid_World))
01725                         continue;
01726 
01727                 /* JRATEST - assert. */
01728                 SMB_ASSERT(curr_ace->owner_type == WORLD_ACE);
01729 
01730                 if (curr_ace->perms == ALL_ACE_PERMS) {
01731 
01732                         /*
01733                          * Optimisation. This is a DENY_ALL to Everyone. Truncate the
01734                          * list at this point including this entry.
01735                          */
01736 
01737                         canon_ace *prev_entry = curr_ace->prev;
01738 
01739                         free_canon_ace_list( curr_ace );
01740                         if (prev_entry)
01741                                 prev_entry->next = NULL;
01742                         else {
01743                                 /* We deleted the entire list. */
01744                                 ace_list = NULL;
01745                         }
01746                         break;
01747                 }
01748 
01749                 for (allow_ace_p = curr_ace->next; allow_ace_p; allow_ace_p = allow_ace_p->next) {
01750 
01751                         /* 
01752                          * Only mask off allow entries.
01753                          */
01754 
01755                         if (allow_ace_p->attr != ALLOW_ACE)
01756                                 continue;
01757 
01758                         allow_ace_p->perms &= ~curr_ace->perms;
01759                 }
01760 
01761                 /*
01762                  * Now it's been applied, remove it.
01763                  */
01764 
01765                 DLIST_REMOVE(ace_list, curr_ace);
01766         }
01767 
01768         /* Pass 2 above - deal with deny user entries. */
01769 
01770         for (curr_ace = ace_list; curr_ace; curr_ace = curr_ace_next) {
01771                 mode_t new_perms = (mode_t)0;
01772                 canon_ace *allow_ace_p;
01773 
01774                 curr_ace_next = curr_ace->next; /* So we can't lose the link. */
01775 
01776                 if (curr_ace->attr != DENY_ACE)
01777                         continue;
01778 
01779                 if (curr_ace->owner_type != UID_ACE)
01780                         continue;
01781 
01782                 if (curr_ace->perms == ALL_ACE_PERMS) {
01783 
01784                         /*
01785                          * Optimisation - this is a deny everything to this user.
01786                          * Convert to an allow nothing and push to the end of the list.
01787                          */
01788 
01789                         curr_ace->attr = ALLOW_ACE;
01790                         curr_ace->perms = (mode_t)0;
01791                         DLIST_DEMOTE(ace_list, curr_ace, canon_ace *);
01792                         continue;
01793                 }
01794 
01795                 for (allow_ace_p = curr_ace->next; allow_ace_p; allow_ace_p = allow_ace_p->next) {
01796 
01797                         if (allow_ace_p->attr != ALLOW_ACE)
01798                                 continue;
01799 
01800                         /* We process GID_ACE and WORLD_ACE entries only. */
01801 
01802                         if (allow_ace_p->owner_type == UID_ACE)
01803                                 continue;
01804 
01805                         if (uid_entry_in_group( curr_ace, allow_ace_p))
01806                                 new_perms |= allow_ace_p->perms;
01807                 }
01808 
01809                 /*
01810                  * Convert to a allow entry, modify the perms and push to the end
01811                  * of the list.
01812                  */
01813 
01814                 curr_ace->attr = ALLOW_ACE;
01815                 curr_ace->perms = (new_perms & ~curr_ace->perms);
01816                 DLIST_DEMOTE(ace_list, curr_ace, canon_ace *);
01817         }
01818 
01819         /* Pass 3 above - deal with deny group entries. */
01820 
01821         for (curr_ace = ace_list; curr_ace; curr_ace = curr_ace_next) {
01822                 canon_ace *allow_ace_p;
01823                 canon_ace *allow_everyone_p = NULL;
01824 
01825                 curr_ace_next = curr_ace->next; /* So we can't lose the link. */
01826 
01827                 if (curr_ace->attr != DENY_ACE)
01828                         continue;
01829 
01830                 if (curr_ace->owner_type != GID_ACE)
01831                         continue;
01832 
01833                 for (allow_ace_p = curr_ace->next; allow_ace_p; allow_ace_p = allow_ace_p->next) {
01834 
01835                         if (allow_ace_p->attr != ALLOW_ACE)
01836                                 continue;
01837 
01838                         /* Store a pointer to the Everyone allow, if it exists. */
01839                         if (allow_ace_p->owner_type == WORLD_ACE)
01840                                 allow_everyone_p = allow_ace_p;
01841 
01842                         /* We process UID_ACE entries only. */
01843 
01844                         if (allow_ace_p->owner_type != UID_ACE)
01845                                 continue;
01846 
01847                         /* Mask off the deny group perms. */
01848 
01849                         if (uid_entry_in_group( allow_ace_p, curr_ace))
01850                                 allow_ace_p->perms &= ~curr_ace->perms;
01851                 }
01852 
01853                 /*
01854                  * Convert the deny to an allow with the correct perms and
01855                  * push to the end of the list.
01856                  */
01857 
01858                 curr_ace->attr = ALLOW_ACE;
01859                 if (allow_everyone_p)
01860                         curr_ace->perms = allow_everyone_p->perms & ~curr_ace->perms;
01861                 else
01862                         curr_ace->perms = (mode_t)0;
01863                 DLIST_DEMOTE(ace_list, curr_ace, canon_ace *);
01864         }
01865 
01866         /* Doing this fourth pass allows Windows semantics to be layered
01867          * on top of POSIX semantics. I'm not sure if this is desirable.
01868          * For example, in W2K ACLs there is no way to say, "Group X no
01869          * access, user Y full access" if user Y is a member of group X.
01870          * This seems completely broken semantics to me.... JRA.
01871          */
01872 
01873 #if 0
01874         /* Pass 4 above - deal with allow entries. */
01875 
01876         for (curr_ace = ace_list; curr_ace; curr_ace = curr_ace_next) {
01877                 canon_ace *allow_ace_p;
01878 
01879                 curr_ace_next = curr_ace->next; /* So we can't lose the link. */
01880 
01881                 if (curr_ace->attr != ALLOW_ACE)
01882                         continue;
01883 
01884                 if (curr_ace->owner_type != UID_ACE)
01885                         continue;
01886 
01887                 for (allow_ace_p = ace_list; allow_ace_p; allow_ace_p = allow_ace_p->next) {
01888 
01889                         if (allow_ace_p->attr != ALLOW_ACE)
01890                                 continue;
01891 
01892                         /* We process GID_ACE entries only. */
01893 
01894                         if (allow_ace_p->owner_type != GID_ACE)
01895                                 continue;
01896 
01897                         /* OR in the group perms. */
01898 
01899                         if (uid_entry_in_group( curr_ace, allow_ace_p))
01900                                 curr_ace->perms |= allow_ace_p->perms;
01901                 }
01902         }
01903 #endif
01904 
01905         *pp_ace_list = ace_list;
01906 }

static mode_t create_default_mode ( files_struct fsp,
BOOL  interitable_mode 
) [static]

posix_acls.c1913 行で定義されています。

参照先 files_struct::connfiles_struct::fsp_namefiles_struct::is_directorymodeunix_mode().

参照元 unpack_canon_ace().

01914 {
01915         int snum = SNUM(fsp->conn);
01916         mode_t and_bits = (mode_t)0;
01917         mode_t or_bits = (mode_t)0;
01918         mode_t mode = interitable_mode
01919                 ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name,
01920                              NULL )
01921                 : S_IRUSR;
01922 
01923         if (fsp->is_directory)
01924                 mode |= (S_IWUSR|S_IXUSR);
01925 
01926         /*
01927          * Now AND with the create mode/directory mode bits then OR with the
01928          * force create mode/force directory mode bits.
01929          */
01930 
01931         if (fsp->is_directory) {
01932                 and_bits = lp_dir_security_mask(snum);
01933                 or_bits = lp_force_dir_security_mode(snum);
01934         } else {
01935                 and_bits = lp_security_mask(snum);
01936                 or_bits = lp_force_security_mode(snum);
01937         }
01938 
01939         return ((mode & and_bits)|or_bits);
01940 }

static BOOL unpack_canon_ace ( files_struct fsp,
SMB_STRUCT_STAT *  pst,
DOM_SID pfile_owner_sid,
DOM_SID pfile_grp_sid,
canon_ace **  ppfile_ace,
canon_ace **  ppdir_ace,
uint32  security_info_sent,
SEC_DESC psd 
) [static]

posix_acls.c1947 行で定義されています。

参照先 create_canon_ace_lists()create_default_mode()security_descriptor_info::daclensure_canon_entry_valid()free_canon_ace_list()merge_aces()print_canon_ace_list()process_deny_list().

参照元 set_nt_acl().

01953 {
01954         canon_ace *file_ace = NULL;
01955         canon_ace *dir_ace = NULL;
01956 
01957         *ppfile_ace = NULL;
01958         *ppdir_ace = NULL;
01959 
01960         if(security_info_sent == 0) {
01961                 DEBUG(0,("unpack_canon_ace: no security info sent !\n"));
01962                 return False;
01963         }
01964 
01965         /*
01966          * If no DACL then this is a chown only security descriptor.
01967          */
01968 
01969         if(!(security_info_sent & DACL_SECURITY_INFORMATION) || !psd->dacl)
01970                 return True;
01971 
01972         /*
01973          * Now go through the DACL and create the canon_ace lists.
01974          */
01975 
01976         if (!create_canon_ace_lists( fsp, pst, pfile_owner_sid, pfile_grp_sid,
01977                                                                 &file_ace, &dir_ace, psd->dacl))
01978                 return False;
01979 
01980         if ((file_ace == NULL) && (dir_ace == NULL)) {
01981                 /* W2K traverse DACL set - ignore. */
01982                 return True;
01983         }
01984 
01985         /*
01986          * Go through the canon_ace list and merge entries
01987          * belonging to identical users of identical allow or deny type.
01988          * We can do this as all deny entries come first, followed by
01989          * all allow entries (we have mandated this before accepting this acl).
01990          */
01991 
01992         print_canon_ace_list( "file ace - before merge", file_ace);
01993         merge_aces( &file_ace );
01994 
01995         print_canon_ace_list( "dir ace - before merge", dir_ace);
01996         merge_aces( &dir_ace );
01997 
01998         /*
01999          * NT ACLs are order dependent. Go through the acl lists and
02000          * process DENY entries by masking the allow entries.
02001          */
02002 
02003         print_canon_ace_list( "file ace - before deny", file_ace);
02004         process_deny_list( &file_ace);
02005 
02006         print_canon_ace_list( "dir ace - before deny", dir_ace);
02007         process_deny_list( &dir_ace);
02008 
02009         /*
02010          * A well formed POSIX file or default ACL has at least 3 entries, a 
02011          * SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ
02012          * and optionally a mask entry. Ensure this is the case.
02013          */
02014 
02015         print_canon_ace_list( "file ace - before valid", file_ace);
02016 
02017         /*
02018          * A default 3 element mode entry for a file should be r-- --- ---.
02019          * A default 3 element mode entry for a directory should be rwx --- ---.
02020          */
02021 
02022         pst->st_mode = create_default_mode(fsp, False);
02023 
02024         if (!ensure_canon_entry_valid(&file_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) {
02025                 free_canon_ace_list(file_ace);
02026                 free_canon_ace_list(dir_ace);
02027                 return False;
02028         }
02029 
02030         print_canon_ace_list( "dir ace - before valid", dir_ace);
02031 
02032         /*
02033          * A default inheritable 3 element mode entry for a directory should be the
02034          * mode Samba will use to create a file within. Ensure user rwx bits are set if
02035          * it's a directory.
02036          */
02037 
02038         pst->st_mode = create_default_mode(fsp, True);
02039 
02040         if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) {
02041                 free_canon_ace_list(file_ace);
02042                 free_canon_ace_list(dir_ace);
02043                 return False;
02044         }
02045 
02046         print_canon_ace_list( "file ace - return", file_ace);
02047         print_canon_ace_list( "dir ace - return", dir_ace);
02048 
02049         *ppfile_ace = file_ace;
02050         *ppdir_ace = dir_ace;
02051         return True;
02052 
02053 }

static void arrange_posix_perms ( char *  filename,
canon_ace **  pp_list_head 
) [static]

posix_acls.c2074 行で定義されています。

参照先 canon_ace::nextSMB_ACL_OTHERSMB_ACL_USER_OBJcanon_ace::type.

02075 {
02076         canon_ace *list_head = *pp_list_head;
02077         canon_ace *owner_ace = NULL;
02078         canon_ace *other_ace = NULL;
02079         canon_ace *ace = NULL;
02080 
02081         for (ace = list_head; ace; ace = ace->next) {
02082                 if (ace->type == SMB_ACL_USER_OBJ)
02083                         owner_ace = ace;
02084                 else if (ace->type == SMB_ACL_OTHER) {
02085                         /* Last ace - this is "other" */
02086                         other_ace = ace;
02087                 }
02088         }
02089                 
02090         if (!owner_ace || !other_ace) {
02091                 DEBUG(0,("arrange_posix_perms: Invalid POSIX permissions for file %s, missing owner or other.\n",
02092                         filename ));
02093                 return;
02094         }
02095 
02096         /*
02097          * The POSIX algorithm applies to owner first, and other last,
02098          * so ensure they are arranged in this order.
02099          */
02100 
02101         if (owner_ace) {
02102                 DLIST_PROMOTE(list_head, owner_ace);
02103         }
02104 
02105         if (other_ace) {
02106                 DLIST_DEMOTE(list_head, other_ace, canon_ace *);
02107         }
02108 
02109         /* We have probably changed the head of the list. */
02110 
02111         *pp_list_head = list_head;
02112 }

static canon_ace* canonicalise_acl ( files_struct fsp,
SMB_ACL_T  posix_acl,
SMB_STRUCT_STAT *  psbuf,
const DOM_SID powner,
const DOM_SID pgroup,
struct pai_val pal,
SMB_ACL_TYPE_T  the_acl_type 
) [static]

posix_acls.c2118 行で定義されています。

参照先 ALLOW_ACEcanon_ace::attrfiles_struct::connconvert_permset_to_mode_t()ensure_canon_entry_valid()get_inherited_flag()posix_id::gidGID_ACEgid_to_sid()global_sid_Worldcanon_ace::inheritedcanon_ace::nextcanon_ace::owner_typecanon_ace::permsprint_canon_ace()sid_copy()SMB_ACL_GROUPSMB_ACL_GROUP_OBJSMB_ACL_MASKSMB_ACL_OTHERSMB_ACL_USERSMB_ACL_USER_OBJcanon_ace::trusteecanon_ace::typeposix_id::uidUID_ACEuid_to_sid()canon_ace::unix_ugposix_id::worldWORLD_ACE.

参照元 get_nt_acl().

02120 {
02121         connection_struct *conn = fsp->conn;
02122         mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR);
02123         canon_ace *list_head = NULL;
02124         canon_ace *ace = NULL;
02125         canon_ace *next_ace = NULL;
02126         int entry_id = SMB_ACL_FIRST_ENTRY;
02127         SMB_ACL_ENTRY_T entry;
02128         size_t ace_count;
02129 
02130         while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
02131                 SMB_ACL_TAG_T tagtype;
02132                 SMB_ACL_PERMSET_T permset;
02133                 DOM_SID sid;
02134                 posix_id unix_ug;
02135                 enum ace_owner owner_type;
02136 
02137                 /* get_next... */
02138                 if (entry_id == SMB_ACL_FIRST_ENTRY)
02139                         entry_id = SMB_ACL_NEXT_ENTRY;
02140 
02141                 /* Is this a MASK entry ? */
02142                 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1)
02143                         continue;
02144 
02145                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1)
02146                         continue;
02147 
02148                 /* Decide which SID to use based on the ACL type. */
02149                 switch(tagtype) {
02150                         case SMB_ACL_USER_OBJ:
02151                                 /* Get the SID from the owner. */
02152                                 sid_copy(&sid, powner);
02153                                 unix_ug.uid = psbuf->st_uid;
02154                                 owner_type = UID_ACE;
02155                                 break;
02156                         case SMB_ACL_USER:
02157                                 {
02158                                         uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
02159                                         if (puid == NULL) {
02160                                                 DEBUG(0,("canonicalise_acl: Failed to get uid.\n"));
02161                                                 continue;
02162                                         }
02163                                         /*
02164                                          * A SMB_ACL_USER entry for the owner is shadowed by the
02165                                          * SMB_ACL_USER_OBJ entry and Windows also cannot represent
02166                                          * that entry, so we ignore it. We also don't create such
02167                                          * entries out of the blue when setting ACLs, so a get/set
02168                                          * cycle will drop them.
02169                                          */
02170                                         if (the_acl_type == SMB_ACL_TYPE_ACCESS && *puid == psbuf->st_uid) {
02171                                                 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
02172                                                 continue;
02173                                         }
02174                                         uid_to_sid( &sid, *puid);
02175                                         unix_ug.uid = *puid;
02176                                         owner_type = UID_ACE;
02177                                         SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
02178                                         break;
02179                                 }
02180                         case SMB_ACL_GROUP_OBJ:
02181                                 /* Get the SID from the owning group. */
02182                                 sid_copy(&sid, pgroup);
02183                                 unix_ug.gid = psbuf->st_gid;
02184                                 owner_type = GID_ACE;
02185                                 break;
02186                         case SMB_ACL_GROUP:
02187                                 {
02188                                         gid_t *pgid = (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
02189                                         if (pgid == NULL) {
02190                                                 DEBUG(0,("canonicalise_acl: Failed to get gid.\n"));
02191                                                 continue;
02192                                         }
02193                                         gid_to_sid( &sid, *pgid);
02194                                         unix_ug.gid = *pgid;
02195                                         owner_type = GID_ACE;
02196                                         SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
02197                                         break;
02198                                 }
02199                         case SMB_ACL_MASK:
02200                                 acl_mask = convert_permset_to_mode_t(conn, permset);
02201                                 continue; /* Don't count the mask as an entry. */
02202                         case SMB_ACL_OTHER:
02203                                 /* Use the Everyone SID */
02204                                 sid = global_sid_World;
02205                                 unix_ug.world = -1;
02206                                 owner_type = WORLD_ACE;
02207                                 break;
02208                         default:
02209                                 DEBUG(0,("canonicalise_acl: Unknown tagtype %u\n", (unsigned int)tagtype));
02210                                 continue;
02211                 }
02212 
02213                 /*
02214                  * Add this entry to the list.
02215                  */
02216 
02217                 if ((ace = SMB_MALLOC_P(canon_ace)) == NULL)
02218                         goto fail;
02219 
02220                 ZERO_STRUCTP(ace);
02221                 ace->type = tagtype;
02222                 ace->perms = convert_permset_to_mode_t(conn, permset);
02223                 ace->attr = ALLOW_ACE;
02224                 ace->trustee = sid;
02225                 ace->unix_ug = unix_ug;
02226                 ace->owner_type = owner_type;
02227                 ace->inherited = get_inherited_flag(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));
02228 
02229                 DLIST_ADD(list_head, ace);
02230         }
02231 
02232         /*
02233          * This next call will ensure we have at least a user/group/world set.
02234          */
02235 
02236         if (!ensure_canon_entry_valid(&list_head, fsp, powner, pgroup, psbuf, False))
02237                 goto fail;
02238 
02239         /*
02240          * Now go through the list, masking the permissions with the
02241          * acl_mask. Ensure all DENY Entries are at the start of the list.
02242          */
02243 
02244         DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default" ));
02245 
02246         for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) {
02247                 next_ace = ace->next;
02248 
02249                 /* Masks are only applied to entries other than USER_OBJ and OTHER. */
02250                 if (ace->type != SMB_ACL_OTHER && ace->type != SMB_ACL_USER_OBJ)
02251                         ace->perms &= acl_mask;
02252 
02253                 if (ace->perms == 0) {
02254                         DLIST_PROMOTE(list_head, ace);
02255                 }
02256 
02257                 if( DEBUGLVL( 10 ) ) {
02258                         print_canon_ace(ace, ace_count);
02259                 }
02260         }
02261 
02262         arrange_posix_perms(fsp->fsp_name,&list_head );
02263 
02264         print_canon_ace_list( "canonicalise_acl: ace entries after arrange", list_head );
02265 
02266         return list_head;
02267 
02268   fail:
02269 
02270         free_canon_ace_list(list_head);
02271         return NULL;
02272 }

static BOOL current_user_in_group ( gid_t  gid  )  [static]

posix_acls.c2278 行で定義されています。

参照先 current_user_unix_token::groups_unix_token::ngroupscurrent_user::ut.

参照元 acl_group_override().

02279 {
02280         int i;
02281 
02282         for (i = 0; i < current_user.ut.ngroups; i++) {
02283                 if (current_user.ut.groups[i] == gid) {
02284                         return True;
02285                 }
02286         }
02287 
02288         return False;
02289 }

static BOOL acl_group_override ( connection_struct conn,
gid_t  prim_gid,
const char *  fname 
) [static]

posix_acls.c2295 行で定義されています。

参照先 can_write_to_file()current_user_in_group()errno.

参照元 set_nt_acl().

02296 {
02297         SMB_STRUCT_STAT sbuf;
02298 
02299         if ((errno != EPERM) && (errno != EACCES)) {
02300                 return False;
02301         }
02302 
02303         /* file primary group == user primary or supplementary group */
02304         if (lp_acl_group_control(SNUM(conn)) && current_user_in_group(prim_gid)) {
02305                 return True;
02306         }
02307 
02308         /* user has writeable permission */
02309         if (lp_dos_filemode(SNUM(conn)) && can_write_to_file(conn, fname, &sbuf)) {
02310                 return True;
02311         }
02312 
02313         return False;
02314 }

static BOOL set_canon_ace_list ( files_struct fsp,
canon_ace the_ace,
BOOL  default_ace,
gid_t  prim_gid,
BOOL pacl_set_support 
) [static]

posix_acls.c2320 行で定義されています。

参照先 files_struct::conncount_canon_ace_list()dbgtext()errnocanon_ace::nextno_acl_syscall_error()canon_ace::permsprint_canon_ace()SMB_ACL_GROUPSMB_ACL_GROUP_OBJSMB_ACL_USERstrerror()canon_ace::type.

参照元 set_nt_acl().

02321 {
02322         connection_struct *conn = fsp->conn;
02323         BOOL ret = False;
02324         SMB_ACL_T the_acl = SMB_VFS_SYS_ACL_INIT(conn, (int)count_canon_ace_list(the_ace) + 1);
02325         canon_ace *p_ace;
02326         int i;
02327         SMB_ACL_ENTRY_T mask_entry;
02328         BOOL got_mask_entry = False;
02329         SMB_ACL_PERMSET_T mask_permset;
02330         SMB_ACL_TYPE_T the_acl_type = (default_ace ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS);
02331         BOOL needs_mask = False;
02332         mode_t mask_perms = 0;
02333 
02334 #if defined(POSIX_ACL_NEEDS_MASK)
02335         /* HP-UX always wants to have a mask (called "class" there). */
02336         needs_mask = True;
02337 #endif
02338 
02339         if (the_acl == NULL) {
02340 
02341                 if (!no_acl_syscall_error(errno)) {
02342                         /*
02343                          * Only print this error message if we have some kind of ACL
02344                          * support that's not working. Otherwise we would always get this.
02345                          */
02346                         DEBUG(0,("set_canon_ace_list: Unable to init %s ACL. (%s)\n",
02347                                 default_ace ? "default" : "file", strerror(errno) ));
02348                 }
02349                 *pacl_set_support = False;
02350                 return False;
02351         }
02352 
02353         if( DEBUGLVL( 10 )) {
02354                 dbgtext("set_canon_ace_list: setting ACL:\n");
02355                 for (i = 0, p_ace = the_ace; p_ace; p_ace = p_ace->next, i++ ) {
02356                         print_canon_ace( p_ace, i);
02357                 }
02358         }
02359 
02360         for (i = 0, p_ace = the_ace; p_ace; p_ace = p_ace->next, i++ ) {
02361                 SMB_ACL_ENTRY_T the_entry;
02362                 SMB_ACL_PERMSET_T the_permset;
02363 
02364                 /*
02365                  * ACLs only "need" an ACL_MASK entry if there are any named user or
02366                  * named group entries. But if there is an ACL_MASK entry, it applies
02367                  * to ACL_USER, ACL_GROUP, and ACL_GROUP_OBJ entries. Set the mask
02368                  * so that it doesn't deny (i.e., mask off) any permissions.
02369                  */
02370 
02371                 if (p_ace->type == SMB_ACL_USER || p_ace->type == SMB_ACL_GROUP) {
02372                         needs_mask = True;
02373                         mask_perms |= p_ace->perms;
02374                 } else if (p_ace->type == SMB_ACL_GROUP_OBJ) {
02375                         mask_perms |= p_ace->perms;
02376                 }
02377 
02378                 /*
02379                  * Get the entry for this ACE.
02380                  */
02381 
02382                 if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) {
02383                         DEBUG(0,("set_canon_ace_list: Failed to create entry %d. (%s)\n",
02384                                 i, strerror(errno) ));
02385                         goto fail;
02386                 }
02387 
02388                 if (p_ace->type == SMB_ACL_MASK) {
02389                         mask_entry = the_entry;
02390                         got_mask_entry = True;
02391                 }
02392 
02393                 /*
02394                  * Ok - we now know the ACL calls should be working, don't
02395                  * allow fallback to chmod.
02396                  */
02397 
02398                 *pacl_set_support = True;
02399 
02400                 /*
02401                  * Initialise the entry from the canon_ace.
02402                  */
02403 
02404                 /*
02405                  * First tell the entry what type of ACE this is.
02406                  */
02407 
02408                 if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, p_ace->type) == -1) {
02409                         DEBUG(0,("set_canon_ace_list: Failed to set tag type on entry %d. (%s)\n",
02410                                 i, strerror(errno) ));
02411                         goto fail;
02412                 }
02413 
02414                 /*
02415                  * Only set the qualifier (user or group id) if the entry is a user
02416                  * or group id ACE.
02417                  */
02418 
02419                 if ((p_ace->type == SMB_ACL_USER) || (p_ace->type == SMB_ACL_GROUP)) {
02420                         if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&p_ace->unix_ug.uid) == -1) {
02421                                 DEBUG(0,("set_canon_ace_list: Failed to set qualifier on entry %d. (%s)\n",
02422                                         i, strerror(errno) ));
02423                                 goto fail;
02424                         }
02425                 }
02426 
02427                 /*
02428                  * Convert the mode_t perms in the canon_ace to a POSIX permset.
02429                  */
02430 
02431                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, the_entry, &the_permset) == -1) {
02432                         DEBUG(0,("set_canon_ace_list: Failed to get permset on entry %d. (%s)\n",
02433                                 i, strerror(errno) ));
02434                         goto fail;
02435                 }
02436 
02437                 if (map_acl_perms_to_permset(conn, p_ace->perms, &the_permset) == -1) {
02438                         DEBUG(0,("set_canon_ace_list: Failed to create permset for mode (%u) on entry %d. (%s)\n",
02439                                 (unsigned int)p_ace->perms, i, strerror(errno) ));
02440                         goto fail;
02441                 }
02442 
02443                 /*
02444                  * ..and apply them to the entry.
02445                  */
02446 
02447                 if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) {
02448                         DEBUG(0,("set_canon_ace_list: Failed to add permset on entry %d. (%s)\n",
02449                                 i, strerror(errno) ));
02450                         goto fail;
02451                 }
02452 
02453                 if( DEBUGLVL( 10 ))
02454                         print_canon_ace( p_ace, i);
02455 
02456         }
02457 
02458         if (needs_mask && !got_mask_entry) {
02459                 if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &mask_entry) == -1) {
02460                         DEBUG(0,("set_canon_ace_list: Failed to create mask entry. (%s)\n", strerror(errno) ));
02461                         goto fail;
02462                 }
02463 
02464                 if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, mask_entry, SMB_ACL_MASK) == -1) {
02465                         DEBUG(0,("set_canon_ace_list: Failed to set tag type on mask entry. (%s)\n",strerror(errno) ));
02466                         goto fail;
02467                 }
02468 
02469                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, mask_entry, &mask_permset) == -1) {
02470                         DEBUG(0,("set_canon_ace_list: Failed to get mask permset. (%s)\n", strerror(errno) ));
02471                         goto fail;
02472                 }
02473 
02474                 if (map_acl_perms_to_permset(conn, S_IRUSR|S_IWUSR|S_IXUSR, &mask_permset) == -1) {
02475                         DEBUG(0,("set_canon_ace_list: Failed to create mask permset. (%s)\n", strerror(errno) ));
02476                         goto fail;
02477                 }
02478 
02479                 if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, mask_entry, mask_permset) == -1) {
02480                         DEBUG(0,("set_canon_ace_list: Failed to add mask permset. (%s)\n", strerror(errno) ));
02481                         goto fail;
02482                 }
02483         }
02484 
02485         /*
02486          * Finally apply it to the file or directory.
02487          */
02488 
02489         if(default_ace || fsp->is_directory || fsp->fh->fd == -1) {
02490                 if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl) == -1) {
02491                         /*
02492                          * Some systems allow all the above calls and only fail with no ACL support
02493                          * when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
02494                          */
02495                         if (no_acl_syscall_error(errno)) {
02496                                 *pacl_set_support = False;
02497                         }
02498 
02499                         if (acl_group_override(conn, prim_gid, fsp->fsp_name)) {
02500                                 int sret;
02501 
02502                                 DEBUG(5,("set_canon_ace_list: acl group control on and current user in file %s primary group.\n",
02503                                         fsp->fsp_name ));
02504 
02505                                 become_root();
02506                                 sret = SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name, the_acl_type, the_acl);
02507                                 unbecome_root();
02508                                 if (sret == 0) {
02509                                         ret = True;     
02510                                 }
02511                         }
02512 
02513                         if (ret == False) {
02514                                 DEBUG(2,("set_canon_ace_list: sys_acl_set_file type %s failed for file %s (%s).\n",
02515                                                 the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
02516                                                 fsp->fsp_name, strerror(errno) ));
02517                                 goto fail;
02518                         }
02519                 }
02520         } else {
02521                 if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, the_acl) == -1) {
02522                         /*
02523                          * Some systems allow all the above calls and only fail with no ACL support
02524                          * when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
02525                          */
02526                         if (no_acl_syscall_error(errno)) {
02527                                 *pacl_set_support = False;
02528                         }
02529 
02530                         if (acl_group_override(conn, prim_gid, fsp->fsp_name)) {
02531                                 int sret;
02532 
02533                                 DEBUG(5,("set_canon_ace_list: acl group control on and current user in file %s primary group.\n",
02534                                         fsp->fsp_name ));
02535 
02536                                 become_root();
02537                                 sret = SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, the_acl);
02538                                 unbecome_root();
02539                                 if (sret == 0) {
02540                                         ret = True;
02541                                 }
02542                         }
02543 
02544                         if (ret == False) {
02545                                 DEBUG(2,("set_canon_ace_list: sys_acl_set_file failed for file %s (%s).\n",
02546                                                 fsp->fsp_name, strerror(errno) ));
02547                                 goto fail;
02548                         }
02549                 }
02550         }
02551 
02552         ret = True;
02553 
02554   fail:
02555 
02556         if (the_acl != NULL) {
02557                 SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
02558         }
02559 
02560         return ret;
02561 }

static struct canon_ace* canon_ace_entry_for ( struct canon_ace list,
SMB_ACL_TAG_T  type,
posix_id id 
) [static]

posix_acls.c2567 行で定義されています。

参照先 idlist()SMB_ACL_GROUPSMB_ACL_USER.

参照元 get_nt_acl().

02568 {
02569         while (list) {
02570                 if (list->type == type && ((type != SMB_ACL_USER && type != SMB_ACL_GROUP) ||
02571                                 (type == SMB_ACL_USER  && id && id->uid == list->unix_ug.uid) ||
02572                                 (type == SMB_ACL_GROUP && id && id->gid == list->unix_ug.gid)))
02573                         break;
02574                 list = list->next;
02575         }
02576         return list;
02577 }

SMB_ACL_T free_empty_sys_acl ( connection_struct conn,
SMB_ACL_T  the_acl 
)

posix_acls.c2583 行で定義されています。

参照元 call_trans2qfilepathinfo()get_nt_acl().

02584 {
02585         SMB_ACL_ENTRY_T entry;
02586 
02587         if (!the_acl)
02588                 return NULL;
02589         if (SMB_VFS_SYS_ACL_GET_ENTRY(conn, the_acl, SMB_ACL_FIRST_ENTRY, &entry) != 1) {
02590                 SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
02591                 return NULL;
02592         }
02593         return the_acl;
02594 }

static BOOL convert_canon_ace_to_posix_perms ( files_struct fsp,
canon_ace file_ace_list,
mode_t *  posix_perms 
) [static]

posix_acls.c2602 行で定義されています。

参照先 files_struct::conncount_canon_ace_list()files_struct::fsp_nameGID_ACEfiles_struct::is_directorycanon_ace::nextcanon_ace::owner_typecanon_ace::permsUID_ACEWORLD_ACE.

参照元 set_nt_acl().

02603 {
02604         int snum = SNUM(fsp->conn);
02605         size_t ace_count = count_canon_ace_list(file_ace_list);
02606         canon_ace *ace_p;
02607         canon_ace *owner_ace = NULL;
02608         canon_ace *group_ace = NULL;
02609         canon_ace *other_ace = NULL;
02610         mode_t and_bits;
02611         mode_t or_bits;
02612 
02613         if (ace_count != 3) {
02614                 DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE entries for file %s to convert to \
02615 posix perms.\n", fsp->fsp_name ));
02616                 return False;
02617         }
02618 
02619         for (ace_p = file_ace_list; ace_p; ace_p = ace_p->next) {
02620                 if (ace_p->owner_type == UID_ACE)
02621                         owner_ace = ace_p;
02622                 else if (ace_p->owner_type == GID_ACE)
02623                         group_ace = ace_p;
02624                 else if (ace_p->owner_type == WORLD_ACE)
02625                         other_ace = ace_p;
02626         }
02627 
02628         if (!owner_ace || !group_ace || !other_ace) {
02629                 DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get standard entries for file %s.\n",
02630                                 fsp->fsp_name ));
02631                 return False;
02632         }
02633 
02634         *posix_perms = (mode_t)0;
02635 
02636         *posix_perms |= owner_ace->perms;
02637         *posix_perms |= MAP_PERM(group_ace->perms, S_IRUSR, S_IRGRP);
02638         *posix_perms |= MAP_PERM(group_ace->perms, S_IWUSR, S_IWGRP);
02639         *posix_perms |= MAP_PERM(group_ace->perms, S_IXUSR, S_IXGRP);
02640         *posix_perms |= MAP_PERM(other_ace->perms, S_IRUSR, S_IROTH);
02641         *posix_perms |= MAP_PERM(other_ace->perms, S_IWUSR, S_IWOTH);
02642         *posix_perms |= MAP_PERM(other_ace->perms, S_IXUSR, S_IXOTH);
02643 
02644         /* The owner must have at least read access. */
02645 
02646         *posix_perms |= S_IRUSR;
02647         if (fsp->is_directory)
02648                 *posix_perms |= (S_IWUSR|S_IXUSR);
02649 
02650         /* If requested apply the masks. */
02651 
02652         /* Get the initial bits to apply. */
02653 
02654         if (fsp->is_directory) {
02655                 and_bits = lp_dir_security_mask(snum);
02656                 or_bits = lp_force_dir_security_mode(snum);
02657         } else {
02658                 and_bits = lp_security_mask(snum);
02659                 or_bits = lp_force_security_mode(snum);
02660         }
02661 
02662         *posix_perms = (((*posix_perms) & and_bits)|or_bits);
02663 
02664         DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o to perm=0%o for file %s.\n",
02665                 (int)owner_ace->perms, (int)group_ace->perms, (int)other_ace->perms, (int)*posix_perms,
02666                 fsp->fsp_name ));
02667 
02668         return True;
02669 }

static size_t merge_default_aces ( SEC_ACE nt_ace_list,
size_t  num_aces 
) [static]

posix_acls.c2678 行で定義されています。

参照先 security_ace_info::flagsflagssid_equal()sizecanon_ace::trusteetype.

参照元 get_nt_acl().

02679 {
02680         size_t i, j;
02681 
02682         for (i = 0; i < num_aces; i++) {
02683                 for (j = i+1; j < num_aces; j++) {
02684                         uint32 i_flags_ni = (nt_ace_list[i].flags & ~SEC_ACE_FLAG_INHERITED_ACE);
02685                         uint32 j_flags_ni = (nt_ace_list[j].flags & ~SEC_ACE_FLAG_INHERITED_ACE);
02686                         BOOL i_inh = (nt_ace_list[i].flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False;
02687                         BOOL j_inh = (nt_ace_list[j].flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False;
02688 
02689                         /* We know the lower number ACE's are file entries. */
02690                         if ((nt_ace_list[i].type == nt_ace_list[j].type) &&
02691                                 (nt_ace_list[i].size == nt_ace_list[j].size) &&
02692                                 (nt_ace_list[i].access_mask == nt_ace_list[j].access_mask) &&
02693                                 sid_equal(&nt_ace_list[i].trustee, &nt_ace_list[j].trustee) &&
02694                                 (i_inh == j_inh) &&
02695                                 (i_flags_ni == 0) &&
02696                                 (j_flags_ni == (SEC_ACE_FLAG_OBJECT_INHERIT|
02697                                                   SEC_ACE_FLAG_CONTAINER_INHERIT|
02698                                                   SEC_ACE_FLAG_INHERIT_ONLY))) {
02699                                 /*
02700                                  * W2K wants to have access allowed zero access ACE's
02701                                  * at the end of the list. If the mask is zero, merge
02702                                  * the non-inherited ACE onto the inherited ACE.
02703                                  */
02704 
02705                                 if (nt_ace_list[i].access_mask == 0) {
02706                                         nt_ace_list[j].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
02707                                                                 (i_inh ? SEC_ACE_FLAG_INHERITED_ACE : 0);
02708                                         if (num_aces - i - 1 > 0)
02709                                                 memmove(&nt_ace_list[i], &nt_ace_list[i+1], (num_aces-i-1) *
02710                                                                 sizeof(SEC_ACE));
02711 
02712                                         DEBUG(10,("merge_default_aces: Merging zero access ACE %u onto ACE %u.\n",
02713                                                 (unsigned int)i, (unsigned int)j ));
02714                                 } else {
02715                                         /*
02716                                          * These are identical except for the flags.
02717                                          * Merge the inherited ACE onto the non-inherited ACE.
02718                                          */
02719 
02720                                         nt_ace_list[i].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
02721                                                                 (i_inh ? SEC_ACE_FLAG_INHERITED_ACE : 0);
02722                                         if (num_aces - j - 1 > 0)
02723                                                 memmove(&nt_ace_list[j], &nt_ace_list[j+1], (num_aces-j-1) *
02724                                                                 sizeof(SEC_ACE));
02725 
02726                                         DEBUG(10,("merge_default_aces: Merging ACE %u onto ACE %u.\n",
02727                                                 (unsigned int)j, (unsigned int)i ));
02728                                 }
02729                                 num_aces--;
02730                                 break;
02731                         }
02732                 }
02733         }
02734 
02735         return num_aces;
02736 }

size_t get_nt_acl ( files_struct fsp,
uint32  security_info,
SEC_DESC **  ppdesc 
)

posix_acls.c2744 行で定義されています。

参照先 security_acl_info::acescanon_ace_entry_for()canonicalise_acl()files_struct::conncount_canon_ace_list()create_file_sids()security_descriptor_info::dacldacl_sort_into_canonical_order()fd_handle::fdfiles_struct::fhfree_canon_ace_list()free_empty_sys_acl()free_inherited_info()files_struct::fsp_nameget_protected_flag()global_sid_Builtin_Administratorsglobal_sid_Builtin_Usersglobal_sid_Creator_Groupglobal_sid_Creator_Ownerinit_sec_access()init_sec_ace()files_struct::is_directoryload_inherited_info()main_loop_talloc_get()make_sec_acl()make_standard_sec_desc()map_canon_ace_perms()merge_default_aces()canon_ace::nextnt4_compatible_acls()security_acl_info::num_acescanon_ace::permsSEC_ACE_TYPE_ACCESS_ALLOWEDsid_copy()SMB_ACL_GROUP_OBJSMB_ACL_OTHERsecurity_ace_info::trusteesecurity_descriptor_info::type.

参照元 aixjfs2_get_nt_acl_common()get_nt_acl_no_snum()gpfsacl_get_nt_acl_common()vfswrap_fget_nt_acl()vfswrap_get_nt_acl().

02745 {
02746         connection_struct *conn = fsp->conn;
02747         SMB_STRUCT_STAT sbuf;
02748         SEC_ACE *nt_ace_list = NULL;
02749         DOM_SID owner_sid;
02750         DOM_SID group_sid;
02751         size_t sd_size = 0;
02752         SEC_ACL *psa = NULL;
02753         size_t num_acls = 0;
02754         size_t num_def_acls = 0;
02755         size_t num_aces = 0;
02756         SMB_ACL_T posix_acl = NULL;
02757         SMB_ACL_T def_acl = NULL;
02758         canon_ace *file_ace = NULL;
02759         canon_ace *dir_ace = NULL;
02760         size_t num_profile_acls = 0;
02761         struct pai_val *pal = NULL;
02762         SEC_DESC *psd = NULL;
02763 
02764         *ppdesc = NULL;
02765 
02766         DEBUG(10,("get_nt_acl: called for file %s\n", fsp->fsp_name ));
02767 
02768         if(fsp->is_directory || fsp->fh->fd == -1) {
02769 
02770                 /* Get the stat struct for the owner info. */
02771                 if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
02772                         return 0;
02773                 }
02774                 /*
02775                  * Get the ACL from the path.
02776                  */
02777 
02778                 posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
02779 
02780                 /*
02781                  * If it's a directory get the default POSIX ACL.
02782                  */
02783 
02784                 if(fsp->is_directory) {
02785                         def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
02786                         def_acl = free_empty_sys_acl(conn, def_acl);
02787                 }
02788 
02789         } else {
02790 
02791                 /* Get the stat struct for the owner info. */
02792                 if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
02793                         return 0;
02794                 }
02795                 /*
02796                  * Get the ACL from the fd.
02797                  */
02798                 posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
02799         }
02800 
02801         DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n",
02802                         posix_acl ? "present" :  "absent",
02803                         def_acl ? "present" :  "absent" ));
02804 
02805         pal = load_inherited_info(fsp);
02806 
02807         /*
02808          * Get the owner, group and world SIDs.
02809          */
02810 
02811         if (lp_profile_acls(SNUM(conn))) {
02812                 /* For WXP SP1 the owner must be administrators. */
02813                 sid_copy(&owner_sid, &global_sid_Builtin_Administrators);
02814                 sid_copy(&group_sid, &global_sid_Builtin_Users);
02815                 num_profile_acls = 2;
02816         } else {
02817                 create_file_sids(&sbuf, &owner_sid, &group_sid);
02818         }
02819 
02820         if ((security_info & DACL_SECURITY_INFORMATION) && !(security_info & PROTECTED_DACL_SECURITY_INFORMATION)) {
02821 
02822                 /*
02823                  * In the optimum case Creator Owner and Creator Group would be used for
02824                  * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this
02825                  * would lead to usability problems under Windows: The Creator entries
02826                  * are only available in browse lists of directories and not for files;
02827                  * additionally the identity of the owning group couldn't be determined.
02828                  * We therefore use those identities only for Default ACLs. 
02829                  */
02830 
02831                 /* Create the canon_ace lists. */
02832                 file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, pal, SMB_ACL_TYPE_ACCESS );
02833 
02834                 /* We must have *some* ACLS. */
02835         
02836                 if (count_canon_ace_list(file_ace) == 0) {
02837                         DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name ));
02838                         goto done;
02839                 }
02840 
02841                 if (fsp->is_directory && def_acl) {
02842                         dir_ace = canonicalise_acl(fsp, def_acl, &sbuf,
02843                                         &global_sid_Creator_Owner,
02844                                         &global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT );
02845                 }
02846 
02847                 /*
02848                  * Create the NT ACE list from the canonical ace lists.
02849                  */
02850 
02851                 {
02852                         canon_ace *ace;
02853                         int nt_acl_type;
02854                         int i;
02855 
02856                         if (nt4_compatible_acls() && dir_ace) {
02857                                 /*
02858                                  * NT 4 chokes if an ACL contains an INHERIT_ONLY entry
02859                                  * but no non-INHERIT_ONLY entry for one SID. So we only
02860                                  * remove entries from the Access ACL if the
02861                                  * corresponding Default ACL entries have also been
02862                                  * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP
02863                                  * are exceptions. We can do nothing
02864                                  * intelligent if the Default ACL contains entries that
02865                                  * are not also contained in the Access ACL, so this
02866                                  * case will still fail under NT 4.
02867                                  */
02868 
02869                                 ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
02870                                 if (ace && !ace->perms) {
02871                                         DLIST_REMOVE(dir_ace, ace);
02872                                         SAFE_FREE(ace);
02873 
02874                                         ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
02875                                         if (ace && !ace->perms) {
02876                                                 DLIST_REMOVE(file_ace, ace);
02877                                                 SAFE_FREE(ace);
02878                                         }
02879                                 }
02880 
02881                                 /*
02882                                  * WinNT doesn't usually have Creator Group
02883                                  * in browse lists, so we send this entry to
02884                                  * WinNT even if it contains no relevant
02885                                  * permissions. Once we can add
02886                                  * Creator Group to browse lists we can
02887                                  * re-enable this.
02888                                  */
02889 
02890 #if 0
02891                                 ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
02892                                 if (ace && !ace->perms) {
02893                                         DLIST_REMOVE(dir_ace, ace);
02894                                         SAFE_FREE(ace);
02895                                 }
02896 #endif
02897 
02898                                 ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
02899                                 if (ace && !ace->perms) {
02900                                         DLIST_REMOVE(file_ace, ace);
02901                                         SAFE_FREE(ace);
02902                                 }
02903                         }
02904 
02905                         num_acls = count_canon_ace_list(file_ace);
02906                         num_def_acls = count_canon_ace_list(dir_ace);
02907 
02908                         /* Allocate the ace list. */
02909                         if ((nt_ace_list = SMB_MALLOC_ARRAY(SEC_ACE,num_acls + num_profile_acls + num_def_acls)) == NULL) {
02910                                 DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
02911                                 goto done;
02912                         }
02913 
02914                         memset(nt_ace_list, '\0', (num_acls + num_def_acls) * sizeof(SEC_ACE) );
02915 
02916                         /*
02917                          * Create the NT ACE list from the canonical ace lists.
02918                          */
02919 
02920                         ace = file_ace;
02921 
02922                         for (i = 0; i < num_acls; i++, ace = ace->next) {
02923                                 SEC_ACCESS acc;
02924 
02925                                 acc = map_canon_ace_perms(SNUM(conn),
02926                                                 &nt_acl_type,
02927                                                 ace->perms,
02928                                                 fsp->is_directory);
02929                                 init_sec_ace(&nt_ace_list[num_aces++],
02930                                         &ace->trustee,
02931                                         nt_acl_type,
02932                                         acc,
02933                                         ace->inherited ?
02934                                                 SEC_ACE_FLAG_INHERITED_ACE : 0);
02935                         }
02936 
02937                         /* The User must have access to a profile share - even
02938                          * if we can't map the SID. */
02939                         if (lp_profile_acls(SNUM(conn))) {
02940                                 SEC_ACCESS acc;
02941 
02942                                 init_sec_access(&acc,FILE_GENERIC_ALL);
02943                                 init_sec_ace(&nt_ace_list[num_aces++],
02944                                                 &global_sid_Builtin_Users,
02945                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
02946                                                 acc, 0);
02947                         }
02948 
02949                         ace = dir_ace;
02950 
02951                         for (i = 0; i < num_def_acls; i++, ace = ace->next) {
02952                                 SEC_ACCESS acc;
02953 
02954                                 acc = map_canon_ace_perms(SNUM(conn),
02955                                                 &nt_acl_type,
02956                                                 ace->perms,
02957                                                 fsp->is_directory);
02958                                 init_sec_ace(&nt_ace_list[num_aces++],
02959                                         &ace->trustee,
02960                                         nt_acl_type,
02961                                         acc,
02962                                         SEC_ACE_FLAG_OBJECT_INHERIT|
02963                                         SEC_ACE_FLAG_CONTAINER_INHERIT|
02964                                         SEC_ACE_FLAG_INHERIT_ONLY|
02965                                         (ace->inherited ?
02966                                            SEC_ACE_FLAG_INHERITED_ACE : 0));
02967                         }
02968 
02969                         /* The User must have access to a profile share - even
02970                          * if we can't map the SID. */
02971                         if (lp_profile_acls(SNUM(conn))) {
02972                                 SEC_ACCESS acc;
02973 
02974                                 init_sec_access(&acc,FILE_GENERIC_ALL);
02975                                 init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
02976                                                 SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
02977                                                 SEC_ACE_FLAG_INHERIT_ONLY|0);
02978                         }
02979 
02980                         /*
02981                          * Merge POSIX default ACLs and normal ACLs into one NT ACE.
02982                          * Win2K needs this to get the inheritance correct when replacing ACLs
02983                          * on a directory tree. Based on work by Jim @ IBM.
02984                          */
02985 
02986                         num_aces = merge_default_aces(nt_ace_list, num_aces);
02987 
02988                 }
02989 
02990                 if (num_aces) {
02991                         if((psa = make_sec_acl( main_loop_talloc_get(), NT4_ACL_REVISION, num_aces, nt_ace_list)) == NULL) {
02992                                 DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
02993                                 goto done;
02994                         }
02995                 }
02996         } /* security_info & DACL_SECURITY_INFORMATION */
02997 
02998         psd = make_standard_sec_desc( main_loop_talloc_get(),
02999                         (security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL,
03000                         (security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL,
03001                         psa,
03002                         &sd_size);
03003 
03004         if(!psd) {
03005                 DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
03006                 sd_size = 0;
03007                 goto done;
03008         }
03009 
03010         /*
03011          * Windows 2000: The DACL_PROTECTED flag in the security
03012          * descriptor marks the ACL as non-inheriting, i.e., no
03013          * ACEs from higher level directories propagate to this
03014          * ACL. In the POSIX ACL model permissions are only
03015          * inherited at file create time, so ACLs never contain
03016          * any ACEs that are inherited dynamically. The DACL_PROTECTED
03017          * flag doesn't seem to bother Windows NT.
03018          * Always set this if map acl inherit is turned off.
03019          */
03020         if (get_protected_flag(pal) || !lp_map_acl_inherit(SNUM(conn))) {
03021                 psd->type |= SE_DESC_DACL_PROTECTED;
03022         }
03023 
03024         if (psd->dacl) {
03025                 dacl_sort_into_canonical_order(psd->dacl->aces, (unsigned int)psd->dacl->num_aces);
03026         }
03027 
03028         *ppdesc = psd;
03029 
03030  done:
03031 
03032         if (posix_acl) {
03033                 SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
03034         }
03035         if (def_acl) {
03036                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
03037         }
03038         free_canon_ace_list(file_ace);
03039         free_canon_ace_list(dir_ace);
03040         free_inherited_info(pal);
03041         SAFE_FREE(nt_ace_list);
03042 
03043         return sd_size;
03044 }

int try_chown ( connection_struct conn,
const char *  fname,
uid_t  uid,
gid_t  gid 
)

posix_acls.c3056 行で定義されています。

参照先 become_root()close_file_fchmod()current_usererrnofd_handle::fdfiles_struct::fhcurrent_user::nt_user_tokenopen_file_fchmod()se_restorese_take_ownership_unix_token::uidunbecome_root()user_has_privileges()current_user::ut.

03057 {
03058         int ret;
03059         files_struct *fsp;
03060         SMB_STRUCT_STAT st;
03061 
03062         if(!CAN_WRITE(conn)) {
03063                 return -1;
03064         }
03065 
03066         /* Case (1). */
03067         /* try the direct way first */
03068         ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
03069         if (ret == 0)
03070                 return 0;
03071 
03072         /* Case (2) / (3) */
03073         if (lp_enable_privileges()) {
03074 
03075                 BOOL has_take_ownership_priv = user_has_privileges(current_user.nt_user_token,
03076                                                               &se_take_ownership);
03077                 BOOL has_restore_priv = user_has_privileges(current_user.nt_user_token,
03078                                                        &se_restore);
03079 
03080                 /* Case (2) */
03081                 if ( ( has_take_ownership_priv && ( uid == current_user.ut.uid ) ) ||
03082                 /* Case (3) */
03083                      ( has_restore_priv ) ) {
03084 
03085                         become_root();
03086                         /* Keep the current file gid the same - take ownership doesn't imply group change. */
03087                         ret = SMB_VFS_CHOWN(conn, fname, uid, (gid_t)-1);
03088                         unbecome_root();
03089                         return ret;
03090                 }
03091         }
03092 
03093         /* Case (4). */
03094         if (!lp_dos_filemode(SNUM(conn))) {
03095                 return -1;
03096         }
03097 
03098         /* only allow chown to the current user. This is more secure,
03099            and also copes with the case where the SID in a take ownership ACL is
03100            a local SID on the users workstation
03101         */
03102         if (uid != current_user.ut.uid) {
03103                 errno = EPERM;
03104                 return -1;
03105         }
03106 
03107         if (SMB_VFS_STAT(conn,fname,&st)) {
03108                 return -1;
03109         }
03110 
03111         if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,&st,&fsp))) {
03112                 return -1;
03113         }
03114 
03115         become_root();
03116         /* Keep the current file gid the same. */
03117         ret = SMB_VFS_FCHOWN(fsp, fsp->fh->fd, uid, (gid_t)-1);
03118         unbecome_root();
03119 
03120         close_file_fchmod(fsp);
03121 
03122         return ret;
03123 }

static NTSTATUS append_parent_acl ( files_struct fsp,
SMB_STRUCT_STAT *  psbuf,
SEC_DESC psd,
SEC_DESC **  pp_new_sd 
) [static]

posix_acls.c3132 行で定義されています。

参照先 security_acl_info::acesclose_file()files_struct::connsecurity_descriptor_info::daclfiles_struct::fsp_namefiles_struct::is_directoryNORMAL_CLOSEsecurity_acl_info::num_acesopen_directory()parent_dirname_talloc()sec_ace_copy()sid_string_static()statustalloc_parent()security_descriptor_info::type.

03136 {
03137         SEC_DESC *parent_sd = NULL;
03138         files_struct *parent_fsp = NULL;
03139         TALLOC_CTX *mem_ctx = talloc_parent(psd);
03140         char *parent_name = NULL;
03141         SEC_ACE *new_ace = NULL;
03142         unsigned int num_aces = psd->dacl->num_aces;
03143         SMB_STRUCT_STAT sbuf;
03144         NTSTATUS status;
03145         int info;
03146         size_t sd_size;
03147         unsigned int i, j;
03148         BOOL is_dacl_protected = (psd->type & SE_DESC_DACL_PROTECTED);
03149 
03150         ZERO_STRUCT(sbuf);
03151 
03152         if (mem_ctx == NULL) {
03153                 return NT_STATUS_NO_MEMORY;
03154         }
03155 
03156         if (!parent_dirname_talloc(mem_ctx,
03157                                 fsp->fsp_name,
03158                                 &parent_name,
03159                                 NULL)) {
03160                 return NT_STATUS_NO_MEMORY;
03161         }
03162 
03163         status = open_directory(fsp->conn,
03164                                 parent_name,
03165                                 &sbuf,
03166                                 FILE_READ_ATTRIBUTES, /* Just a stat open */
03167                                 FILE_SHARE_NONE, /* Ignored for stat opens */
03168                                 FILE_OPEN,
03169                                 0,
03170                                 0,
03171                                 &info,
03172                                 &parent_fsp);
03173 
03174         if (!NT_STATUS_IS_OK(status)) {
03175                 return status;
03176         }
03177 
03178         sd_size = SMB_VFS_GET_NT_ACL(parent_fsp, parent_fsp->fsp_name,
03179                         DACL_SECURITY_INFORMATION, &parent_sd );
03180 
03181         close_file(parent_fsp, NORMAL_CLOSE);
03182 
03183         if (!sd_size) {
03184                 return NT_STATUS_ACCESS_DENIED;
03185         }
03186 
03187         /*
03188          * Make room for potentially all the ACLs from
03189          * the parent. We used to add the ugw triple here,
03190          * as we knew we were dealing with POSIX ACLs.
03191          * We no longer need to do so as we can guarentee
03192          * that a default ACL from the parent directory will
03193          * be well formed for POSIX ACLs if it came from a
03194          * POSIX ACL source, and if we're not writing to a
03195          * POSIX ACL sink then we don't care if it's not well
03196          * formed. JRA.
03197          */
03198 
03199         num_aces += parent_sd->dacl->num_aces;
03200 
03201         if((new_ace = TALLOC_ZERO_ARRAY(mem_ctx, SEC_ACE,
03202                                         num_aces)) == NULL) {
03203                 return NT_STATUS_NO_MEMORY;
03204         }
03205 
03206         /* Start by copying in all the given ACE entries. */
03207         for (i = 0; i < psd->dacl->num_aces; i++) {
03208                 sec_ace_copy(&new_ace[i], &psd->dacl->aces[i]);
03209         }
03210 
03211         /*
03212          * Note that we're ignoring "inherit permissions" here
03213          * as that really only applies to newly created files. JRA.
03214          */
03215 
03216         /* Finally append any inherited ACEs. */
03217         for (j = 0; j < parent_sd->dacl->num_aces; j++) {
03218                 SEC_ACE *se = &parent_sd->dacl->aces[j];
03219 
03220                 if (fsp->is_directory) {
03221                         if (!(se->flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
03222                                 /* Doesn't apply to a directory - ignore. */
03223                                 DEBUG(10,("append_parent_acl: directory %s "
03224                                         "ignoring non container "
03225                                         "inherit flags %u on ACE with sid %s "
03226                                         "from parent %s\n",
03227                                         fsp->fsp_name,
03228                                         (unsigned int)se->flags,
03229                                         sid_string_static(&se->trustee),
03230                                         parent_name));
03231                                 continue;
03232                         }
03233                 } else {
03234                         if (!(se->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
03235                                 /* Doesn't apply to a file - ignore. */
03236                                 DEBUG(10,("append_parent_acl: file %s "
03237                                         "ignoring non object "
03238                                         "inherit flags %u on ACE with sid %s "
03239                                         "from parent %s\n",
03240                                         fsp->fsp_name,
03241                                         (unsigned int)se->flags,
03242                                         sid_string_static(&se->trustee),
03243                                         parent_name));
03244                                 continue;
03245                         }
03246                 }
03247 
03248                 if (is_dacl_protected) {
03249                         /* If the DACL is protected it means we must
03250                          * not overwrite an existing ACE entry with the
03251                          * same SID. This is order N^2. Ouch :-(. JRA. */
03252                         unsigned int k;
03253                         for (k = 0; k < psd->dacl->num_aces; k++) {
03254                                 if (sid_equal(&psd->dacl->aces[k].trustee,
03255                                                 &se->trustee)) {
03256                                         break;
03257                                 }
03258                         }
03259                         if (k < psd->dacl->num_aces) {
03260                                 /* SID matched. Ignore. */
03261                                 DEBUG(10,("append_parent_acl: path %s "
03262                                         "ignoring ACE with protected sid %s "
03263                                         "from parent %s\n",
03264                                         fsp->fsp_name,
03265                                         sid_string_static(&se->trustee),
03266                                         parent_name));
03267                                 continue;
03268                         }
03269                 }
03270 
03271                 sec_ace_copy(&new_ace[i], se);
03272                 if (se->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
03273                         new_ace[i].flags &= ~(SEC_ACE_FLAG_VALID_INHERIT);
03274                 }
03275                 new_ace[i].flags |= SEC_ACE_FLAG_INHERITED_ACE;
03276 
03277                 if (fsp->is_directory) {
03278                         /*
03279                          * Strip off any inherit only. It's applied.
03280                          */
03281                         new_ace[i].flags &= ~(SEC_ACE_FLAG_INHERIT_ONLY);
03282                         if (se->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
03283                                 /* No further inheritance. */
03284                                 new_ace[i].flags &=
03285                                         ~(SEC_ACE_FLAG_CONTAINER_INHERIT|
03286                                         SEC_ACE_FLAG_OBJECT_INHERIT);
03287                         }
03288                 } else {
03289                         /*
03290                          * Strip off any container or inherit
03291                          * flags, they can't apply to objects.
03292                          */
03293                         new_ace[i].flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|
03294                                                 SEC_ACE_FLAG_INHERIT_ONLY|
03295                                                 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
03296                 }
03297 
03298                 i++;
03299 
03300                 DEBUG(10,("append_parent_acl: path %s "
03301                         "inheriting ACE with sid %s "
03302                         "from parent %s\n",
03303                         fsp->fsp_name,
03304                         sid_string_static(&se->trustee),
03305                         parent_name));
03306 
03307         }
03308 
03309         parent_sd->dacl->aces = new_ace;
03310         parent_sd->dacl->num_aces = i;
03311 
03312         *pp_new_sd = parent_sd;
03313         return status;
03314 }

BOOL set_nt_acl ( files_struct fsp,
uint32  security_info_sent,
SEC_DESC psd 
)

posix_acls.c3324 行で定義されています。

参照先 acl_group_override()become_root()files_struct::connconvert_canon_ace_to_posix_perms()create_file_sids()security_descriptor_info::daclerrnofd_handle::fdfiles_struct::fhfree_canon_ace_list()files_struct::fsp_namefiles_struct::is_directoryset_canon_ace_list()store_inheritance_attributes()strerror()try_chown()security_descriptor_info::typeunbecome_root()unpack_canon_ace()unpack_nt_owners().

参照元 aixjfs2_set_nt_acl_common()gpfsacl_set_nt_acl_internal()vfswrap_fset_nt_acl()vfswrap_set_nt_acl().

03325 {
03326         connection_struct *conn = fsp->conn;
03327         uid_t user = (uid_t)-1;
03328         gid_t grp = (gid_t)-1;
03329         SMB_STRUCT_STAT sbuf;
03330         DOM_SID file_owner_sid;
03331         DOM_SID file_grp_sid;
03332         canon_ace *file_ace_list = NULL;
03333         canon_ace *dir_ace_list = NULL;
03334         BOOL acl_perms = False;
03335         mode_t orig_mode = (mode_t)0;
03336         BOOL set_acl_as_root = False;
03337         BOOL acl_set_support = False;
03338         BOOL ret = False;
03339 
03340         DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
03341 
03342         if (!CAN_WRITE(conn)) {
03343                 DEBUG(10,("set acl rejected on read-only share\n"));
03344                 return False;
03345         }
03346 
03347         /*
03348          * Get the current state of the file.
03349          */
03350 
03351         if(fsp->is_directory || fsp->fh->fd == -1) {
03352                 if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0)
03353                         return False;
03354         } else {
03355                 if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0)
03356                         return False;
03357         }
03358 
03359         /* Save the original element we check against. */
03360         orig_mode = sbuf.st_mode;
03361 
03362         /*
03363          * Unpack the user/group/world id's.
03364          */
03365 
03366         if (!unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd)) {
03367                 return False;
03368         }
03369 
03370         /*
03371          * Do we need to chown ?
03372          */
03373 
03374         if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) {
03375 
03376                 DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
03377                                 fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
03378 
03379                 if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
03380                         DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n",
03381                                 fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
03382                         return False;
03383                 }
03384 
03385                 /*
03386                  * Recheck the current state of the file, which may have changed.
03387                  * (suid/sgid bits, for instance)
03388                  */
03389 
03390                 if(fsp->is_directory) {
03391                         if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf) != 0) {
03392                                 return False;
03393                         }
03394                 } else {
03395 
03396                         int sret;
03397 
03398                         if(fsp->fh->fd == -1)
03399                                 sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
03400                         else
03401                                 sret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf);
03402 
03403                         if(sret != 0)
03404                                 return False;
03405                 }
03406 
03407                 /* Save the original element we check against. */
03408                 orig_mode = sbuf.st_mode;
03409 
03410                 /* If we successfully chowned, we know we must
03411                  * be able to set the acl, so do it as root.
03412                  */
03413                 set_acl_as_root = True;
03414         }
03415 
03416         create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
03417 
03418         acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
03419                                         &file_ace_list, &dir_ace_list, security_info_sent, psd);
03420 
03421         /* Ignore W2K traverse DACL set. */
03422         if (!file_ace_list && !dir_ace_list) {
03423                 return True;
03424         }
03425  
03426         if (!acl_perms) {
03427                 DEBUG(3,("set_nt_acl: cannot set permissions\n"));
03428                 free_canon_ace_list(file_ace_list);
03429                 free_canon_ace_list(dir_ace_list);
03430                 return False;
03431         }
03432  
03433         /*
03434          * Only change security if we got a DACL.
03435          */
03436  
03437         if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) {
03438                 free_canon_ace_list(file_ace_list);
03439                 free_canon_ace_list(dir_ace_list);
03440                 return True;
03441         }
03442  
03443         /*
03444          * Try using the POSIX ACL set first. Fall back to chmod if
03445          * we have no ACL support on this filesystem.
03446          */
03447  
03448         if (acl_perms && file_ace_list) {
03449                 if (set_acl_as_root) {
03450                         become_root();
03451                 }
03452                 ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support);
03453                 if (set_acl_as_root) {
03454                         unbecome_root();
03455                 }
03456                 if (acl_set_support && ret == false) {
03457                         DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) ));
03458                         free_canon_ace_list(file_ace_list);
03459                         free_canon_ace_list(dir_ace_list);
03460                         return ret;
03461                 }
03462         }
03463  
03464         if (acl_perms && acl_set_support && fsp->is_directory) {
03465                 if (dir_ace_list) {
03466                         if (set_acl_as_root) {
03467                                 become_root();
03468                         }
03469                         ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support);
03470                         if (set_acl_as_root) {
03471                                 unbecome_root();
03472                         }
03473                         if (ret == False) {
03474                                 DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) ));
03475                                 free_canon_ace_list(file_ace_list);
03476                                 free_canon_ace_list(dir_ace_list);
03477                                 return ret;
03478                         }
03479                 } else {
03480                         int sret = -1;
03481  
03482                         /*
03483                          * No default ACL - delete one if it exists.
03484                          */
03485  
03486                         if (set_acl_as_root) {
03487                                 become_root();
03488                         }
03489                         sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name);
03490                         if (set_acl_as_root) {
03491                                 unbecome_root();
03492                         }
03493                         if (sret == -1) {
03494                                 if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
03495                                         DEBUG(5,("set_nt_acl: acl group control on and "
03496                                                 "current user in file %s primary group. Override delete_def_acl\n",
03497                                                 fsp->fsp_name ));
03498  
03499                                         become_root();
03500                                         sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name);
03501                                         unbecome_root();
03502                                 }
03503  
03504                                 if (sret == -1) {
03505                                         DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
03506                                         free_canon_ace_list(file_ace_list);
03507                                         free_canon_ace_list(dir_ace_list);
03508                                         return False;
03509                                 }
03510                         }
03511                 }
03512         }
03513  
03514         if (acl_set_support) {
03515                 if (set_acl_as_root) {
03516                         become_root();
03517                 }
03518                 store_inheritance_attributes(fsp, file_ace_list, dir_ace_list,
03519                                 (psd->type & SE_DESC_DACL_PROTECTED) ? True : False);
03520                 if (set_acl_as_root) {
03521                         unbecome_root();
03522                 }
03523         }
03524  
03525         /*
03526          * If we cannot set using POSIX ACLs we fall back to checking if we need to chmod.
03527          */
03528  
03529         if(!acl_set_support && acl_perms) {
03530                 mode_t posix_perms;
03531  
03532                 if (!convert_canon_ace_to_posix_perms( fsp, file_ace_list, &posix_perms)) {
03533                         free_canon_ace_list(file_ace_list);
03534                         free_canon_ace_list(dir_ace_list);
03535                         DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n",
03536                                 fsp->fsp_name ));
03537                         return False;
03538                 }
03539  
03540                 if (orig_mode != posix_perms) {
03541                         int sret = -1;
03542  
03543                         DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
03544                                 fsp->fsp_name, (unsigned int)posix_perms ));
03545  
03546                         if (set_acl_as_root) {
03547                                 become_root();
03548                         }
03549                         sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms);
03550                         if (set_acl_as_root) {
03551                                 unbecome_root();
03552                         }
03553                         if(sret == -1) {
03554                                 if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
03555                                         DEBUG(5,("set_nt_acl: acl group control on and "
03556                                                 "current user in file %s primary group. Override chmod\n",
03557                                                 fsp->fsp_name ));
03558  
03559                                         become_root();
03560                                         sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms);
03561                                         unbecome_root();
03562                                 }
03563  
03564                                 if (sret == -1) {
03565                                         DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n",
03566                                                 fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) ));
03567                                         free_canon_ace_list(file_ace_list);
03568                                         free_canon_ace_list(dir_ace_list);
03569                                         return False;
03570                                 }
03571                         }
03572                 }
03573         }
03574  
03575         free_canon_ace_list(file_ace_list);
03576         free_canon_ace_list(dir_ace_list);
03577         return True;
03578 }

int get_acl_group_bits ( connection_struct conn,
const char *  fname,
mode_t *  mode 
)

posix_acls.c3586 行で定義されています。

参照先 resultSMB_ACL_GROUP_OBJ.

参照元 set_ea_dos_attribute().

03587 {
03588         int entry_id = SMB_ACL_FIRST_ENTRY;
03589         SMB_ACL_ENTRY_T entry;
03590         SMB_ACL_T posix_acl;
03591         int result = -1;
03592 
03593         posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
03594         if (posix_acl == (SMB_ACL_T)NULL)
03595                 return -1;
03596 
03597         while (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) {
03598                 SMB_ACL_TAG_T tagtype;
03599                 SMB_ACL_PERMSET_T permset;
03600 
03601                 /* get_next... */
03602                 if (entry_id == SMB_ACL_FIRST_ENTRY)
03603                         entry_id = SMB_ACL_NEXT_ENTRY;
03604 
03605                 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) ==-1)
03606                         break;
03607 
03608                 if (tagtype == SMB_ACL_GROUP_OBJ) {
03609                         if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
03610                                 break;
03611                         } else {
03612                                 *mode &= ~(S_IRGRP|S_IWGRP|S_IXGRP);
03613                                 *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRGRP : 0);
03614                                 *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWGRP : 0);
03615                                 *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXGRP : 0);
03616                                 result = 0;
03617                                 break;
03618                         }
03619                 }
03620         }
03621         SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
03622         return result;
03623 }

static int chmod_acl_internals ( connection_struct conn,
SMB_ACL_T  posix_acl,
mode_t  mode 
) [static]

posix_acls.c3630 行で定義されています。

参照先 map_acl_perms_to_permset()pai_val::num_entriespermsSMB_ACL_GROUP_OBJSMB_ACL_MASKSMB_ACL_OTHERSMB_ACL_USER_OBJunix_perms_to_acl_perms().

参照元 copy_access_acl()fchmod_acl().

03631 {
03632         int entry_id = SMB_ACL_FIRST_ENTRY;
03633         SMB_ACL_ENTRY_T entry;
03634         int num_entries = 0;
03635 
03636         while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) {
03637                 SMB_ACL_TAG_T tagtype;
03638                 SMB_ACL_PERMSET_T permset;
03639                 mode_t perms;
03640 
03641                 /* get_next... */
03642                 if (entry_id == SMB_ACL_FIRST_ENTRY)
03643                         entry_id = SMB_ACL_NEXT_ENTRY;
03644 
03645                 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1)
03646                         return -1;
03647 
03648                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1)
03649                         return -1;
03650 
03651                 num_entries++;
03652 
03653                 switch(tagtype) {
03654                         case SMB_ACL_USER_OBJ:
03655                                 perms = unix_perms_to_acl_perms(mode, S_IRUSR, S_IWUSR, S_IXUSR);
03656                                 break;
03657                         case SMB_ACL_GROUP_OBJ:
03658                                 perms = unix_perms_to_acl_perms(mode, S_IRGRP, S_IWGRP, S_IXGRP);
03659                                 break;
03660                         case SMB_ACL_MASK:
03661                                 /*
03662                                  * FIXME: The ACL_MASK entry permissions should really be set to
03663                                  * the union of the permissions of all ACL_USER,
03664                                  * ACL_GROUP_OBJ, and ACL_GROUP entries. That's what
03665                                  * acl_calc_mask() does, but Samba ACLs doesn't provide it.
03666                                  */
03667                                 perms = S_IRUSR|S_IWUSR|S_IXUSR;
03668                                 break;
03669                         case SMB_ACL_OTHER:
03670                                 perms = unix_perms_to_acl_perms(mode, S_IROTH, S_IWOTH, S_IXOTH);
03671                                 break;
03672                         default:
03673                                 continue;
03674                 }
03675 
03676                 if (map_acl_perms_to_permset(conn, perms, &permset) == -1)
03677                         return -1;
03678 
03679                 if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) == -1)
03680                         return -1;
03681         }
03682 
03683         /*
03684          * If this is a simple 3 element ACL or no elements then it's a standard
03685          * UNIX permission set. Just use chmod...       
03686          */
03687 
03688         if ((num_entries == 3) || (num_entries == 0))
03689                 return -1;
03690 
03691         return 0;
03692 }

static int copy_access_acl ( connection_struct conn,
const char *  from,
const char *  to,
mode_t  mode 
) [static]

posix_acls.c3700 行で定義されています。

参照先 chmod_acl_internals().

参照元 chmod_acl()inherit_access_acl().

03701 {
03702         SMB_ACL_T posix_acl = NULL;
03703         int ret = -1;
03704 
03705         if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL)
03706                 return -1;
03707 
03708         if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
03709                 goto done;
03710 
03711         ret = SMB_VFS_SYS_ACL_SET_FILE(conn, to, SMB_ACL_TYPE_ACCESS, posix_acl);
03712 
03713  done:
03714 
03715         SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
03716         return ret;
03717 }

int chmod_acl ( connection_struct conn,
const char *  name,
mode_t  mode 
)

posix_acls.c3725 行で定義されています。

参照先 copy_access_acl().

参照元 vfswrap_chmod_acl().

03726 {
03727         return copy_access_acl(conn, name, name, mode);
03728 }

int inherit_access_acl ( connection_struct conn,
const char *  inherit_from_dir,
const char *  name,
mode_t  mode 
)

posix_acls.c3735 行で定義されています。

参照先 copy_access_acl()directory_has_default_acl().

参照元 mkdir_internal()open_file()smb_unix_mknod().

03737 {
03738         if (directory_has_default_acl(conn, inherit_from_dir))
03739                 return 0;
03740 
03741         return copy_access_acl(conn, inherit_from_dir, name, mode);
03742 }

int fchmod_acl ( files_struct fsp,
int  fd,
mode_t  mode 
)

posix_acls.c3749 行で定義されています。

参照先 chmod_acl_internals()files_struct::conn.

参照元 vfswrap_fchmod_acl().

03750 {
03751         connection_struct *conn = fsp->conn;
03752         SMB_ACL_T posix_acl = NULL;
03753         int ret = -1;
03754 
03755         if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fd)) == NULL)
03756                 return -1;
03757 
03758         if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
03759                 goto done;
03760 
03761         ret = SMB_VFS_SYS_ACL_SET_FD(fsp, fd, posix_acl);
03762 
03763   done:
03764 
03765         SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
03766         return ret;
03767 }

BOOL directory_has_default_acl ( connection_struct conn,
const char *  fname 
)

posix_acls.c3773 行で定義されています。

参照元 inherit_access_acl()open_file_ntcreate()vfswrap_mkdir().

03774 {
03775         SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
03776         BOOL has_acl = False;
03777         SMB_ACL_ENTRY_T entry;
03778 
03779         if (def_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, def_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) {
03780                 has_acl = True;
03781         }
03782 
03783         if (def_acl) {
03784                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
03785         }
03786         return has_acl;
03787 }

static BOOL unix_ex_wire_to_permset ( connection_struct conn,
unsigned char  wire_perm,
SMB_ACL_PERMSET_T p_permset 
) [static]

posix_acls.c3793 行で定義されています。

参照元 create_posix_acl_from_wire().

03794 {
03795         if (wire_perm & ~(SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE)) {
03796                 return False;
03797         }
03798 
03799         if (SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, *p_permset) ==  -1) {
03800                 return False;
03801         }
03802 
03803         if (wire_perm & SMB_POSIX_ACL_READ) {
03804                 if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1) {
03805                         return False;
03806                 }
03807         }
03808         if (wire_perm & SMB_POSIX_ACL_WRITE) {
03809                 if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1) {
03810                         return False;
03811                 }
03812         }
03813         if (wire_perm & SMB_POSIX_ACL_EXECUTE) {
03814                 if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1) {
03815                         return False;
03816                 }
03817         }
03818         return True;
03819 }

static BOOL unix_ex_wire_to_tagtype ( unsigned char  wire_tt,
SMB_ACL_TAG_T p_tt 
) [static]

posix_acls.c3825 行で定義されています。

参照先 SMB_ACL_GROUPSMB_ACL_GROUP_OBJSMB_ACL_MASKSMB_ACL_OTHERSMB_ACL_USERSMB_ACL_USER_OBJ.

参照元 create_posix_acl_from_wire().

03826 {
03827         switch (wire_tt) {
03828                 case SMB_POSIX_ACL_USER_OBJ:
03829                         *p_tt = SMB_ACL_USER_OBJ;
03830                         break;
03831                 case SMB_POSIX_ACL_USER:
03832                         *p_tt = SMB_ACL_USER;
03833                         break;
03834                 case SMB_POSIX_ACL_GROUP_OBJ:
03835                         *p_tt = SMB_ACL_GROUP_OBJ;
03836                         break;
03837                 case SMB_POSIX_ACL_GROUP:
03838                         *p_tt = SMB_ACL_GROUP;
03839                         break;
03840                 case SMB_POSIX_ACL_MASK:
03841                         *p_tt = SMB_ACL_MASK;
03842                         break;
03843                 case SMB_POSIX_ACL_OTHER:
03844                         *p_tt = SMB_ACL_OTHER;
03845                         break;
03846                 default:
03847                         return False;
03848         }
03849         return True;
03850 }

static SMB_ACL_T create_posix_acl_from_wire ( connection_struct conn,
uint16  num_acls,
const char *  pdata 
) [static]

posix_acls.c3857 行で定義されています。

参照先 errnoSMB_ACL_GROUPSMB_ACL_USERstrerror()unix_ex_wire_to_permset()unix_ex_wire_to_tagtype().

参照元 set_unix_posix_acl()set_unix_posix_default_acl().

03858 {
03859         unsigned int i;
03860         SMB_ACL_T the_acl = SMB_VFS_SYS_ACL_INIT(conn, num_acls);
03861 
03862         if (the_acl == NULL) {
03863                 return NULL;
03864         }
03865 
03866         for (i = 0; i < num_acls; i++) {
03867                 SMB_ACL_ENTRY_T the_entry;
03868                 SMB_ACL_PERMSET_T the_permset;
03869                 SMB_ACL_TAG_T tag_type;
03870 
03871                 if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) {
03872                         DEBUG(0,("create_posix_acl_from_wire: Failed to create entry %u. (%s)\n",
03873                                 i, strerror(errno) ));
03874                         goto fail;
03875                 }
03876 
03877                 if (!unix_ex_wire_to_tagtype(CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)), &tag_type)) {
03878                         DEBUG(0,("create_posix_acl_from_wire: invalid wire tagtype %u on entry %u.\n",
03879                                 CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)), i ));
03880                         goto fail;
03881                 }
03882 
03883                 if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, tag_type) == -1) {
03884                         DEBUG(0,("create_posix_acl_from_wire: Failed to set tagtype on entry %u. (%s)\n",
03885                                 i, strerror(errno) ));
03886                         goto fail;
03887                 }
03888 
03889                 /* Get the permset pointer from the new ACL entry. */
03890                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, the_entry, &the_permset) == -1) {
03891                         DEBUG(0,("create_posix_acl_from_wire: Failed to get permset on entry %u. (%s)\n",
03892                                 i, strerror(errno) ));
03893                         goto fail;
03894                 }
03895 
03896                 /* Map from wire to permissions. */
03897                 if (!unix_ex_wire_to_permset(conn, CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+1), &the_permset)) {
03898                         DEBUG(0,("create_posix_acl_from_wire: invalid permset %u on entry %u.\n",
03899                                 CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE) + 1), i ));
03900                         goto fail;
03901                 }
03902 
03903                 /* Now apply to the new ACL entry. */
03904                 if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) {
03905                         DEBUG(0,("create_posix_acl_from_wire: Failed to add permset on entry %u. (%s)\n",
03906                                 i, strerror(errno) ));
03907                         goto fail;
03908                 }
03909 
03910                 if (tag_type == SMB_ACL_USER) {
03911                         uint32 uidval = IVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
03912                         uid_t uid = (uid_t)uidval;
03913                         if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&uid) == -1) {
03914                                 DEBUG(0,("create_posix_acl_from_wire: Failed to set uid %u on entry %u. (%s)\n",
03915                                         (unsigned int)uid, i, strerror(errno) ));
03916                                 goto fail;
03917                         }
03918                 }
03919 
03920                 if (tag_type == SMB_ACL_GROUP) {
03921                         uint32 gidval = IVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
03922                         gid_t gid = (uid_t)gidval;
03923                         if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&gid) == -1) {
03924                                 DEBUG(0,("create_posix_acl_from_wire: Failed to set gid %u on entry %u. (%s)\n",
03925                                         (unsigned int)gid, i, strerror(errno) ));
03926                                 goto fail;
03927                         }
03928                 }
03929         }
03930 
03931         return the_acl;
03932 
03933  fail:
03934 
03935         if (the_acl != NULL) {
03936                 SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
03937         }
03938         return NULL;
03939 }

BOOL set_unix_posix_default_acl ( connection_struct conn,
const char *  fname,
SMB_STRUCT_STAT *  psbuf,
uint16  num_def_acls,
const char *  pdata 
)

posix_acls.c3948 行で定義されています。

参照先 create_posix_acl_from_wire()errnostrerror().

参照元 smb_set_posix_acl().

03950 {
03951         SMB_ACL_T def_acl = NULL;
03952 
03953         if (num_def_acls && !S_ISDIR(psbuf->st_mode)) {
03954                 DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname ));
03955                 errno = EISDIR;
03956                 return False;
03957         }
03958 
03959         if (!num_def_acls) {
03960                 /* Remove the default ACL. */
03961                 if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fname) == -1) {
03962                         DEBUG(5,("set_unix_posix_default_acl: acl_delete_def_file failed on directory %s (%s)\n",
03963                                 fname, strerror(errno) ));
03964                         return False;
03965                 }
03966                 return True;
03967         }
03968 
03969         if ((def_acl = create_posix_acl_from_wire(conn, num_def_acls, pdata)) == NULL) {
03970                 return False;
03971         }
03972 
03973         if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
03974                 DEBUG(5,("set_unix_posix_default_acl: acl_set_file failed on directory %s (%s)\n",
03975                         fname, strerror(errno) ));
03976                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
03977                 return False;
03978         }
03979 
03980         DEBUG(10,("set_unix_posix_default_acl: set default acl for file %s\n", fname ));
03981         SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
03982         return True;
03983 }

static BOOL remove_posix_acl ( connection_struct conn,
files_struct fsp,
const char *  fname 
) [static]

posix_acls.c3993 行で定義されています。

参照先 errnofd_handle::fdfiles_struct::fhSMB_ACL_GROUP_OBJSMB_ACL_OTHERSMB_ACL_USER_OBJstrerror().

参照元 set_unix_posix_acl().

03994 {
03995         SMB_ACL_T file_acl = NULL;
03996         int entry_id = SMB_ACL_FIRST_ENTRY;
03997         SMB_ACL_ENTRY_T entry;
03998         BOOL ret = False;
03999         /* Create a new ACL with only 3 entries, u/g/w. */
04000         SMB_ACL_T new_file_acl = SMB_VFS_SYS_ACL_INIT(conn, 3);
04001         SMB_ACL_ENTRY_T user_ent = NULL;
04002         SMB_ACL_ENTRY_T group_ent = NULL;
04003         SMB_ACL_ENTRY_T other_ent = NULL;
04004 
04005         if (new_file_acl == NULL) {
04006                 DEBUG(5,("remove_posix_acl: failed to init new ACL with 3 entries for file %s.\n", fname));
04007                 return False;
04008         }
04009 
04010         /* Now create the u/g/w entries. */
04011         if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &user_ent) == -1) {
04012                 DEBUG(5,("remove_posix_acl: Failed to create user entry for file %s. (%s)\n",
04013                         fname, strerror(errno) ));
04014                 goto done;
04015         }
04016         if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, user_ent, SMB_ACL_USER_OBJ) == -1) {
04017                 DEBUG(5,("remove_posix_acl: Failed to set user entry for file %s. (%s)\n",
04018                         fname, strerror(errno) ));
04019                 goto done;
04020         }
04021 
04022         if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &group_ent) == -1) {
04023                 DEBUG(5,("remove_posix_acl: Failed to create group entry for file %s. (%s)\n",
04024                         fname, strerror(errno) ));
04025                 goto done;
04026         }
04027         if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, group_ent, SMB_ACL_GROUP_OBJ) == -1) {
04028                 DEBUG(5,("remove_posix_acl: Failed to set group entry for file %s. (%s)\n",
04029                         fname, strerror(errno) ));
04030                 goto done;
04031         }
04032 
04033         if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &other_ent) == -1) {
04034                 DEBUG(5,("remove_posix_acl: Failed to create other entry for file %s. (%s)\n",
04035                         fname, strerror(errno) ));
04036                 goto done;
04037         }
04038         if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, other_ent, SMB_ACL_OTHER) == -1) {
04039                 DEBUG(5,("remove_posix_acl: Failed to set other entry for file %s. (%s)\n",
04040                         fname, strerror(errno) ));
04041                 goto done;
04042         }
04043 
04044         /* Get the current file ACL. */
04045         if (fsp && fsp->fh->fd != -1) {
04046                 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
04047         } else {
04048                 file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS);
04049         }
04050 
04051         if (file_acl == NULL) {
04052                 /* This is only returned if an error occurred. Even for a file with
04053                    no acl a u/g/w acl should be returned. */
04054                 DEBUG(5,("remove_posix_acl: failed to get ACL from file %s (%s).\n",
04055                         fname, strerror(errno) ));
04056                 goto done;
04057         }
04058 
04059         while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, file_acl, entry_id, &entry) == 1) {
04060                 SMB_ACL_TAG_T tagtype;
04061                 SMB_ACL_PERMSET_T permset;
04062 
04063                 /* get_next... */
04064                 if (entry_id == SMB_ACL_FIRST_ENTRY)
04065                         entry_id = SMB_ACL_NEXT_ENTRY;
04066 
04067                 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
04068                         DEBUG(5,("remove_posix_acl: failed to get tagtype from ACL on file %s (%s).\n",
04069                                 fname, strerror(errno) ));
04070                         goto done;
04071                 }
04072 
04073                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
04074                         DEBUG(5,("remove_posix_acl: failed to get permset from ACL on file %s (%s).\n",
04075                                 fname, strerror(errno) ));
04076                         goto done;
04077                 }
04078 
04079                 if (tagtype == SMB_ACL_USER_OBJ) {
04080                         if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, user_ent, permset) == -1) {
04081                                 DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
04082                                         fname, strerror(errno) ));
04083                         }
04084                 } else if (tagtype == SMB_ACL_GROUP_OBJ) {
04085                         if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, group_ent, permset) == -1) {
04086                                 DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
04087                                         fname, strerror(errno) ));
04088                         }
04089                 } else if (tagtype == SMB_ACL_OTHER) {
04090                         if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, other_ent, permset) == -1) {
04091                                 DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
04092                                         fname, strerror(errno) ));
04093                         }
04094                 }
04095         }
04096 
04097         /* Set the new empty file ACL. */
04098         if (fsp && fsp->fh->fd != -1) {
04099                 if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, new_file_acl) == -1) {
04100                         DEBUG(5,("remove_posix_acl: acl_set_file failed on %s (%s)\n",
04101                                 fname, strerror(errno) ));
04102                         goto done;
04103                 }
04104         } else {
04105                 if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS, new_file_acl) == -1) {
04106                         DEBUG(5,("remove_posix_acl: acl_set_file failed on %s (%s)\n",
04107                                 fname, strerror(errno) ));
04108                         goto done;
04109                 }
04110         }
04111 
04112         ret = True;
04113 
04114  done:
04115 
04116         if (file_acl) {
04117                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
04118         }
04119         if (new_file_acl) {
04120                 SMB_VFS_SYS_ACL_FREE_ACL(conn, new_file_acl);
04121         }
04122         return ret;
04123 }

BOOL set_unix_posix_acl ( connection_struct conn,
files_struct fsp,
const char *  fname,
uint16  num_acls,
const char *  pdata 
)

posix_acls.c4131 行で定義されています。

参照先 create_posix_acl_from_wire()errnofd_handle::fdfiles_struct::fhremove_posix_acl()strerror().

参照元 smb_set_posix_acl().

04132 {
04133         SMB_ACL_T file_acl = NULL;
04134 
04135         if (!num_acls) {
04136                 /* Remove the ACL from the file. */
04137                 return remove_posix_acl(conn, fsp, fname);
04138         }
04139 
04140         if ((file_acl = create_posix_acl_from_wire(conn, num_acls, pdata)) == NULL) {
04141                 return False;
04142         }
04143 
04144         if (fsp && fsp->fh->fd != -1) {
04145                 /* The preferred way - use an open fd. */
04146                 if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, file_acl) == -1) {
04147                         DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
04148                                 fname, strerror(errno) ));
04149                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
04150                         return False;
04151                 }
04152         } else {
04153                 if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS, file_acl) == -1) {
04154                         DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
04155                                 fname, strerror(errno) ));
04156                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
04157                         return False;
04158                 }
04159         }
04160 
04161         DEBUG(10,("set_unix_posix_acl: set acl for file %s\n", fname ));
04162         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
04163         return True;
04164 }

static NTSTATUS conn_get_nt_acl ( TALLOC_CTX mem_ctx,
struct connection_struct conn,
const char *  fname,
SMB_STRUCT_STAT *  psbuf,
struct security_descriptor_info **  psd 
) [static]

posix_acls.c4173 行で定義されています。

参照先 close_file()errnomap_nt_error_from_unix()NORMAL_CLOSEnt_errstr()open_directory()open_file_stat()status.

参照元 can_access_file_acl().

04178 {
04179         NTSTATUS status;
04180         struct files_struct *fsp = NULL;
04181         struct security_descriptor_info *secdesc = NULL;
04182         size_t secdesc_size;
04183 
04184         if (!VALID_STAT(*psbuf)) {
04185                 if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
04186                         return map_nt_error_from_unix(errno);
04187                 }
04188         }
04189 
04190         /* fake a files_struct ptr: */
04191 
04192         if (S_ISDIR(psbuf->st_mode)) {
04193                 status = open_directory(conn, fname, psbuf,
04194                                         READ_CONTROL_ACCESS,
04195                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
04196                                         FILE_OPEN,
04197                                         0,
04198                                         FILE_ATTRIBUTE_DIRECTORY,
04199                                         NULL, &fsp);
04200         }
04201         else {
04202                 status = open_file_stat(conn, fname, psbuf, &fsp);
04203         }
04204 
04205         if (!NT_STATUS_IS_OK(status)) {
04206                 DEBUG(3, ("Unable to open file %s: %s\n", fname,
04207                           nt_errstr(status)));
04208                 return status;
04209         }
04210 
04211         secdesc_size = SMB_VFS_GET_NT_ACL(fsp, fname,
04212                                           (OWNER_SECURITY_INFORMATION |
04213                                            GROUP_SECURITY_INFORMATION |
04214                                            DACL_SECURITY_INFORMATION),
04215                                           &secdesc);
04216         if (secdesc_size == 0) {
04217                 DEBUG(5, ("Unable to get NT ACL for file %s\n", fname));
04218                 status = NT_STATUS_ACCESS_DENIED;
04219                 goto done;
04220         }
04221 
04222         *psd = talloc_move(mem_ctx, &secdesc);
04223         status = NT_STATUS_OK;
04224 
04225 done:
04226         close_file(fsp, NORMAL_CLOSE);
04227         return status;
04228 }

static BOOL can_access_file_acl ( struct connection_struct conn,
const char *  fname,
SMB_STRUCT_STAT *  psbuf,
uint32_t  access_mask 
) [static]

posix_acls.c4230 行で定義されています。

参照先 conn_get_nt_acl()current_usernt_errstr()current_user::nt_user_tokenresultse_access_check()statustmp_talloc_ctx().

参照元 can_access_file()can_delete_file_in_directory().

04233 {
04234         BOOL result;
04235         NTSTATUS status;
04236         uint32_t access_granted;
04237         struct security_descriptor_info *secdesc = NULL;
04238 
04239         status = conn_get_nt_acl(tmp_talloc_ctx(), conn, fname, psbuf, &secdesc);
04240         if (!NT_STATUS_IS_OK(status)) {
04241                 DEBUG(5, ("Could not get acl: %s\n", nt_errstr(status)));
04242                 return False;
04243         }
04244 
04245         result = se_access_check(secdesc, current_user.nt_user_token,
04246                                  access_mask, &access_granted, &status);
04247         TALLOC_FREE(secdesc);
04248         return result;
04249 }

BOOL can_delete_file_in_directory ( connection_struct conn,
const char *  fname 
)

posix_acls.c4256 行で定義されています。

参照先 connection_struct::admin_usercan_access_file_acl()current_usererrnoparent_dirname()_unix_token::uidcurrent_user::ut.

参照元 call_nt_transact_create()reply_ntcreate_and_X().

04257 {
04258         SMB_STRUCT_STAT sbuf;  
04259         pstring dname;
04260 
04261         if (!CAN_WRITE(conn)) {
04262                 return False;
04263         }
04264 
04265         /* Get the parent directory permission mask and owners. */
04266         pstrcpy(dname, parent_dirname(fname));
04267         if(SMB_VFS_STAT(conn, dname, &sbuf) != 0) {
04268                 return False;
04269         }
04270 
04271         /* fast paths first */
04272 
04273         if (!S_ISDIR(sbuf.st_mode)) {
04274                 return False;
04275         }
04276         if (current_user.ut.uid == 0 || conn->admin_user) {
04277                 /* I'm sorry sir, I didn't know you were root... */
04278                 return True;
04279         }
04280 
04281         /* Check primary owner write access. */
04282         if (current_user.ut.uid == sbuf.st_uid) {
04283                 return (sbuf.st_mode & S_IWUSR) ? True : False;
04284         }
04285 
04286 #ifdef S_ISVTX
04287         /* sticky bit means delete only by owner or root. */
04288         if (sbuf.st_mode & S_ISVTX) {
04289                 SMB_STRUCT_STAT sbuf_file;  
04290                 if(SMB_VFS_STAT(conn, fname, &sbuf_file) != 0) {
04291                         if (errno == ENOENT) {
04292                                 /* If the file doesn't already exist then
04293                                  * yes we'll be able to delete it. */
04294                                 return True;
04295                         }
04296                         return False;
04297                 }
04298                 /*
04299                  * Patch from SATOH Fumiyasu <fumiyas@miraclelinux.com>
04300                  * for bug #3348. Don't assume owning sticky bit
04301                  * directory means write access allowed.
04302                  */
04303                 if (current_user.ut.uid != sbuf_file.st_uid) {
04304                         return False;
04305                 }
04306         }
04307 #endif
04308 
04309         /* now for ACL checks */
04310 
04311         return can_access_file_acl(conn, dname, &sbuf, FILE_WRITE_DATA);
04312 }

BOOL can_access_file ( connection_struct conn,
const char *  fname,
SMB_STRUCT_STAT *  psbuf,
uint32  access_mask 
)

posix_acls.c4320 行で定義されています。

参照先 connection_struct::admin_usercan_access_file_acl()current_user_unix_token::uidcurrent_user::ut.

参照元 can_write_to_file()open_file_ntcreate().

04321 {
04322         if (!(access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))) {
04323                 return False;
04324         }
04325         access_mask &= (FILE_READ_DATA|FILE_WRITE_DATA);
04326 
04327         /* some fast paths first */
04328 
04329         DEBUG(10,("can_access_file: requesting 0x%x on file %s\n",
04330                 (unsigned int)access_mask, fname ));
04331 
04332         if (current_user.ut.uid == 0 || conn->admin_user) {
04333                 /* I'm sorry sir, I didn't know you were root... */
04334                 return True;
04335         }
04336 
04337         if (!VALID_STAT(*psbuf)) {
04338                 /* Get the file permission mask and owners. */
04339                 if(SMB_VFS_STAT(conn, fname, psbuf) != 0) {
04340                         return False;
04341                 }
04342         }
04343 
04344         /* Check primary owner access. */
04345         if (current_user.ut.uid == psbuf->st_uid) {
04346                 switch (access_mask) {
04347                         case FILE_READ_DATA:
04348                                 return (psbuf->st_mode & S_IRUSR) ? True : False;
04349 
04350                         case FILE_WRITE_DATA:
04351                                 return (psbuf->st_mode & S_IWUSR) ? True : False;
04352 
04353                         default: /* FILE_READ_DATA|FILE_WRITE_DATA */
04354 
04355                                 if ((psbuf->st_mode & (S_IWUSR|S_IRUSR)) == (S_IWUSR|S_IRUSR)) {
04356                                         return True;
04357                                 } else {
04358                                         return False;
04359                                 }
04360                 }
04361         }
04362 
04363         /* now for ACL checks */
04364 
04365         return can_access_file_acl(conn, fname, psbuf, access_mask);
04366 }

BOOL can_write_to_file ( connection_struct conn,
const char *  fname,
SMB_STRUCT_STAT *  psbuf 
)

posix_acls.c4373 行で定義されています。

参照先 can_access_file().

参照元 acl_group_override()call_nt_transact_create()dos_mode_from_sbuf()reply_ntcreate_and_X()set_ea_dos_attribute().

04374 {
04375         return can_access_file(conn, fname, psbuf, FILE_WRITE_DATA);
04376 }

SEC_DESC* get_nt_acl_no_snum ( TALLOC_CTX ctx,
const char *  fname 
)

posix_acls.c4388 行で定義されています。

参照先 files_struct::connconn_free_internal()dup_sec_desc()fd_handle::fdfiles_struct::fhfiles_struct::fnumfiles_struct::fsp_nameget_nt_acl()connection_struct::mem_ctxconnection_struct::paramsshare_params::serviceset_conn_connectpath()smbd_vfs_init()talloc_init().

参照元 elog_check_access().

04389 {
04390         SEC_DESC *psd, *ret_sd;
04391         connection_struct conn;
04392         files_struct finfo;
04393         struct fd_handle fh;
04394         pstring path;
04395         pstring filename;
04396         
04397         ZERO_STRUCT( conn );
04398         
04399         if ( !(conn.mem_ctx = talloc_init( "novfs_get_nt_acl" )) ) {
04400                 DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n"));
04401                 return NULL;
04402         }
04403 
04404         if (!(conn.params = TALLOC_P(conn.mem_ctx, struct share_params))) {
04405                 DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n"));
04406                 TALLOC_FREE(conn.mem_ctx);
04407                 return NULL;
04408         }
04409 
04410         conn.params->service = -1;
04411         
04412         pstrcpy( path, "/" );
04413         set_conn_connectpath(&conn, path);
04414         
04415         if (!smbd_vfs_init(&conn)) {
04416                 DEBUG(0,("get_nt_acl_no_snum: Unable to create a fake connection struct!\n"));
04417                 conn_free_internal( &conn );
04418                 return NULL;
04419         }
04420         
04421         ZERO_STRUCT( finfo );
04422         ZERO_STRUCT( fh );
04423         
04424         finfo.fnum = -1;
04425         finfo.conn = &conn;
04426         finfo.fh = &fh;
04427         finfo.fh->fd = -1;
04428         pstrcpy( filename, fname );
04429         finfo.fsp_name = filename;
04430         
04431         if (get_nt_acl( &finfo, DACL_SECURITY_INFORMATION, &psd ) == 0) {
04432                 DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n"));
04433                 conn_free_internal( &conn );
04434                 return NULL;
04435         }
04436         
04437         ret_sd = dup_sec_desc( ctx, psd );
04438         
04439         conn_free_internal( &conn );
04440         
04441         return ret_sd;
04442 }


変数

struct current_user current_user

smbrun.c24 行で定義されています。

struct generic_mapping file_generic_mapping

secdesc.c28 行で定義されています。

参照元 create_canon_ace_lists()get_share_security_default()map_generic_share_sd_bits()open_file_ntcreate()parse_usershare_acl().


Sambaに対してSat Aug 29 21:24:28 2009に生成されました。  doxygen 1.4.7