データ構造 | |
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_val * | create_pai_val (char *buf, size_t size) |
static struct pai_val * | load_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_ace * | dup_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_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 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_ace * | canon_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_DESC * | get_nt_acl_no_snum (TALLOC_CTX *ctx, const char *fname) |
変数 | |
current_user | current_user |
generic_mapping | file_generic_mapping |
enum ace_owner |
enum ace_attribute |
static uint32 get_pai_entry_val | ( | struct pai_entry * | paie | ) | [static] |
posix_acls.c の 98 行で定義されています。
参照先 posix_id::gid・GID_ACE・pai_entry::owner_type・posix_id::uid・UID_ACE・pai_entry::unix_ug・WORLD_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.c の 118 行で定義されています。
参照先 posix_id::gid・GID_ACE・canon_ace::owner_type・posix_id::uid・UID_ACE・canon_ace::unix_ug・WORLD_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.c の 138 行で定義されています。
参照先 canon_ace::inherited・canon_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.c の 152 行で定義されています。
参照先 get_entry_val()・canon_ace::inherited・canon_ace::next・canon_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.c の 215 行で定義されています。
参照先 files_struct::conn・create_pai_buf()・errno・fd_handle::fd・files_struct::fh・files_struct::fsp_name・no_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.c の 259 行で定義されています。
参照先 pai_val::def_entry_list・pai_val::entry_list・pai_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 }
posix_acls.c の 279 行で定義されています。
参照元 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.c の 290 行で定義されています。
参照先 pai_val::def_entry_list・pai_val::entry_list・get_entry_val()・get_pai_entry_val()・pai_entry::next・pai_entry::owner_type・canon_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.c の 310 行で定義されています。
参照元 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.c の 340 行で定義されています。
参照先 check_pai_ok()・pai_val::def_entry_list・pai_val::entry_list・free_inherited_info()・GID_ACE・pai_val::num_def_entries・pai_val::num_entries・pai_val::pai_protected・UID_ACE・WORLD_ACE.
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.c の 434 行で定義されています。
参照先 files_struct::conn・create_pai_val()・errno・fd_handle::fd・files_struct::fh・files_struct::fsp_name・pai_val::pai_protected・strerror().
参照元 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.c の 502 行で定義されています。
参照先 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.c の 517 行で定義されています。
参照先 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 }
posix_acls.c の 532 行で定義されています。
参照先 canon_ace::next・canon_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.c の 548 行で定義されています。
参照先 ALLOW_ACE・canon_ace::attr・dbgtext()・posix_id::gid・GID_ACE・gidtoname()・canon_ace::inherited・canon_ace::owner_type・canon_ace::perms・sid_to_string()・SMB_ACL_GROUP・SMB_ACL_GROUP_OBJ・SMB_ACL_OTHER・SMB_ACL_USER・SMB_ACL_USER_OBJ・canon_ace::trustee・canon_ace::type・posix_id::uid・UID_ACE・uidtoname()・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.c の 594 行で定義されています。
参照先 dbgtext()・canon_ace::next・print_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.c の 609 行で定義されています。
参照元 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.c の 624 行で定義されています。
参照元 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.c の 643 行で定義されています。
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.c の 666 行で定義されています。
参照先 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 }
posix_acls.c の 676 行で定義されています。
参照先 posix_id::gid・GID_ACE・canon_ace::owner_type・sid_equal()・canon_ace::trustee・posix_id::uid・UID_ACE・canon_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.c の 699 行で定義されています。
参照先 canon_ace::attr・dbgtext()・identity_in_ace_equal()・canon_ace::next・canon_ace::perms・print_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.c の 811 行で定義されています。
参照先 ACL_COMPAT_AUTO・ACL_COMPAT_WINNT・get_remote_arch()・ra_type・RA_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.c の 831 行で定義されています。
参照先 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.c の 888 行で定義されています。
参照先 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.c の 929 行で定義されています。
参照先 current_user・_unix_token::gid・security_descriptor_info::group_sid・security_descriptor_info::owner_sid・sid_copy()・sid_string_static()・sid_to_gid()・sid_to_uid()・_unix_token::uid・current_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.c の 1001 行で定義されています。
参照先 files_struct::conn・files_struct::is_directory・canon_ace::perms・unix_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 }
posix_acls.c の 1045 行で定義されています。
参照先 current_user・_unix_token::gid・posix_id::gid・global_sid_World・sid_equal()・canon_ace::trustee・_unix_token::uid・posix_id::uid・uidtoname()・canon_ace::unix_ug・user_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.c の 1073 行で定義されています。
参照先 apply_default_perms()・got_user・canon_ace::next・SMB_ACL_GROUP_OBJ・SMB_ACL_USER_OBJ・canon_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.c の 1217 行で定義されています。
参照先 count_canon_ace_list()・GID_ACE・canon_ace::next・sid_equal()・SMB_ACL_GROUP_OBJ・SMB_ACL_USER_OBJ・UID_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(¤t_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(¤t_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.c の 1260 行で定義されています。
参照先 security_acl_info::aces・file_generic_mapping・files_struct::is_directory・nt4_compatible_acls()・security_acl_info::num_aces・se_map_generic()・SEC_ACE_TYPE_ACCESS_ALLOWED・SEC_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(¤t_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(¤t_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(¤t_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(¤t_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( ¤t_ace->trustee, ¤t_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( ¤t_ace->trustee, ¤t_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, ¤t_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.c の 1700 行で定義されています。
参照先 canon_ace::attr・DENY_ACE・free_canon_ace_list()・global_sid_World・canon_ace::next・canon_ace::owner_type・canon_ace::perms・canon_ace::prev・sid_equal()・canon_ace::trustee・WORLD_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.c の 1913 行で定義されています。
参照先 files_struct::conn・files_struct::fsp_name・files_struct::is_directory・mode・unix_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.c の 1947 行で定義されています。
参照先 create_canon_ace_lists()・create_default_mode()・security_descriptor_info::dacl・ensure_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.c の 2074 行で定義されています。
参照先 canon_ace::next・SMB_ACL_OTHER・SMB_ACL_USER_OBJ・canon_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.c の 2118 行で定義されています。
参照先 ALLOW_ACE・canon_ace::attr・files_struct::conn・convert_permset_to_mode_t()・ensure_canon_entry_valid()・get_inherited_flag()・posix_id::gid・GID_ACE・gid_to_sid()・global_sid_World・canon_ace::inherited・canon_ace::next・canon_ace::owner_type・canon_ace::perms・print_canon_ace()・sid_copy()・SMB_ACL_GROUP・SMB_ACL_GROUP_OBJ・SMB_ACL_MASK・SMB_ACL_OTHER・SMB_ACL_USER・SMB_ACL_USER_OBJ・canon_ace::trustee・canon_ace::type・posix_id::uid・UID_ACE・uid_to_sid()・canon_ace::unix_ug・posix_id::world・WORLD_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.c の 2278 行で定義されています。
参照先 current_user・_unix_token::groups・_unix_token::ngroups・current_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.c の 2295 行で定義されています。
参照先 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.c の 2320 行で定義されています。
参照先 files_struct::conn・count_canon_ace_list()・dbgtext()・errno・canon_ace::next・no_acl_syscall_error()・canon_ace::perms・print_canon_ace()・SMB_ACL_GROUP・SMB_ACL_GROUP_OBJ・SMB_ACL_USER・strerror()・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.c の 2567 行で定義されています。
参照先 id・list()・SMB_ACL_GROUP・SMB_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.c の 2583 行で定義されています。
参照元 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.c の 2602 行で定義されています。
参照先 files_struct::conn・count_canon_ace_list()・files_struct::fsp_name・GID_ACE・files_struct::is_directory・canon_ace::next・canon_ace::owner_type・canon_ace::perms・UID_ACE・WORLD_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.c の 2678 行で定義されています。
参照先 security_ace_info::flags・flags・sid_equal()・size・canon_ace::trustee・type.
参照元 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.c の 2744 行で定義されています。
参照先 security_acl_info::aces・canon_ace_entry_for()・canonicalise_acl()・files_struct::conn・count_canon_ace_list()・create_file_sids()・security_descriptor_info::dacl・dacl_sort_into_canonical_order()・fd_handle::fd・files_struct::fh・free_canon_ace_list()・free_empty_sys_acl()・free_inherited_info()・files_struct::fsp_name・get_protected_flag()・global_sid_Builtin_Administrators・global_sid_Builtin_Users・global_sid_Creator_Group・global_sid_Creator_Owner・init_sec_access()・init_sec_ace()・files_struct::is_directory・load_inherited_info()・main_loop_talloc_get()・make_sec_acl()・make_standard_sec_desc()・map_canon_ace_perms()・merge_default_aces()・canon_ace::next・nt4_compatible_acls()・security_acl_info::num_aces・canon_ace::perms・SEC_ACE_TYPE_ACCESS_ALLOWED・sid_copy()・SMB_ACL_GROUP_OBJ・SMB_ACL_OTHER・security_ace_info::trustee・security_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.c の 3056 行で定義されています。
参照先 become_root()・close_file_fchmod()・current_user・errno・fd_handle::fd・files_struct::fh・current_user::nt_user_token・open_file_fchmod()・se_restore・se_take_ownership・_unix_token::uid・unbecome_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.c の 3132 行で定義されています。
参照先 security_acl_info::aces・close_file()・files_struct::conn・security_descriptor_info::dacl・files_struct::fsp_name・files_struct::is_directory・NORMAL_CLOSE・security_acl_info::num_aces・open_directory()・parent_dirname_talloc()・sec_ace_copy()・sid_string_static()・status・talloc_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.c の 3324 行で定義されています。
参照先 acl_group_override()・become_root()・files_struct::conn・convert_canon_ace_to_posix_perms()・create_file_sids()・security_descriptor_info::dacl・errno・fd_handle::fd・files_struct::fh・free_canon_ace_list()・files_struct::fsp_name・files_struct::is_directory・set_canon_ace_list()・store_inheritance_attributes()・strerror()・try_chown()・security_descriptor_info::type・unbecome_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.c の 3586 行で定義されています。
参照先 result・SMB_ACL_GROUP_OBJ.
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.c の 3630 行で定義されています。
参照先 map_acl_perms_to_permset()・pai_val::num_entries・perms・SMB_ACL_GROUP_OBJ・SMB_ACL_MASK・SMB_ACL_OTHER・SMB_ACL_USER_OBJ・unix_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.c の 3700 行で定義されています。
参照元 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.c の 3725 行で定義されています。
参照先 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.c の 3735 行で定義されています。
参照先 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.c の 3749 行で定義されています。
参照先 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.c の 3773 行で定義されています。
参照元 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.c の 3793 行で定義されています。
参照元 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.c の 3825 行で定義されています。
参照先 SMB_ACL_GROUP・SMB_ACL_GROUP_OBJ・SMB_ACL_MASK・SMB_ACL_OTHER・SMB_ACL_USER・SMB_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.c の 3857 行で定義されています。
参照先 errno・SMB_ACL_GROUP・SMB_ACL_USER・strerror()・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.c の 3948 行で定義されています。
参照先 create_posix_acl_from_wire()・errno・strerror().
参照元 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.c の 3993 行で定義されています。
参照先 errno・fd_handle::fd・files_struct::fh・SMB_ACL_GROUP_OBJ・SMB_ACL_OTHER・SMB_ACL_USER_OBJ・strerror().
参照元 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.c の 4131 行で定義されています。
参照先 create_posix_acl_from_wire()・errno・fd_handle::fd・files_struct::fh・remove_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.c の 4173 行で定義されています。
参照先 close_file()・errno・map_nt_error_from_unix()・NORMAL_CLOSE・nt_errstr()・open_directory()・open_file_stat()・status.
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.c の 4230 行で定義されています。
参照先 conn_get_nt_acl()・current_user・nt_errstr()・current_user::nt_user_token・result・se_access_check()・status・tmp_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.c の 4256 行で定義されています。
参照先 connection_struct::admin_user・can_access_file_acl()・current_user・errno・parent_dirname()・_unix_token::uid・current_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.c の 4320 行で定義されています。
参照先 connection_struct::admin_user・can_access_file_acl()・current_user・_unix_token::uid・current_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.c の 4373 行で定義されています。
参照先 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.c の 4388 行で定義されています。
参照先 files_struct::conn・conn_free_internal()・dup_sec_desc()・fd_handle::fd・files_struct::fh・files_struct::fnum・files_struct::fsp_name・get_nt_acl()・connection_struct::mem_ctx・connection_struct::params・share_params::service・set_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 |