modules/nfs4_acls.c

説明を見る。
00001 /*
00002  * NFS4 ACL handling
00003  *
00004  * Copyright (C) Jim McDonough, 2006
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "includes.h"
00022 #include "nfs4_acls.h"
00023 
00024 #define SMBACL4_PARAM_TYPE_NAME "nfs4"
00025 
00026 #define SMB_ACE4_INT_MAGIC 0x76F8A967
00027 typedef struct _SMB_ACE4_INT_T
00028 {
00029         uint32  magic;
00030         SMB_ACE4PROP_T  prop;
00031         void    *next;
00032 } SMB_ACE4_INT_T;
00033 
00034 #define SMB_ACL4_INT_MAGIC 0x29A3E792
00035 typedef struct _SMB_ACL4_INT_T
00036 {
00037         uint32  magic;
00038         uint32  naces;
00039         SMB_ACE4_INT_T  *first;
00040         SMB_ACE4_INT_T  *last;
00041 } SMB_ACL4_INT_T;
00042 
00043 extern struct current_user current_user;
00044 extern int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid);
00045 extern BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp,
00046         uint32 security_info_sent, SEC_DESC *psd);
00047 
00048 static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *acl)
00049 {
00050         SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)acl;
00051         if (acl==NULL)
00052         {
00053                 DEBUG(2, ("acl is NULL\n"));
00054                 errno = EINVAL;
00055                 return NULL;
00056         }
00057         if (aclint->magic!=SMB_ACL4_INT_MAGIC)
00058         {
00059                 DEBUG(2, ("aclint bad magic 0x%x\n", aclint->magic));
00060                 errno = EINVAL;
00061                 return NULL;
00062         }
00063         return aclint;
00064 }
00065 
00066 static SMB_ACE4_INT_T *get_validated_aceint(SMB4ACE_T *ace)
00067 {
00068         SMB_ACE4_INT_T *aceint = (SMB_ACE4_INT_T *)ace;
00069         if (ace==NULL)
00070         {
00071                 DEBUG(2, ("ace is NULL\n"));
00072                 errno = EINVAL;
00073                 return NULL;
00074         }
00075         if (aceint->magic!=SMB_ACE4_INT_MAGIC)
00076         {
00077                 DEBUG(2, ("aceint bad magic 0x%x\n", aceint->magic));
00078                 errno = EINVAL;
00079                 return NULL;
00080         }
00081         return aceint;
00082 }
00083 
00084 SMB4ACL_T *smb_create_smb4acl(void)
00085 {
00086         TALLOC_CTX *mem_ctx = main_loop_talloc_get();
00087         SMB_ACL4_INT_T  *acl = (SMB_ACL4_INT_T *)TALLOC_SIZE(mem_ctx, sizeof(SMB_ACL4_INT_T));
00088         if (acl==NULL)
00089         {
00090                 DEBUG(0, ("TALLOC_SIZE failed\n"));
00091                 errno = ENOMEM;
00092                 return NULL;
00093         }
00094         memset(acl, 0, sizeof(SMB_ACL4_INT_T));
00095         acl->magic = SMB_ACL4_INT_MAGIC;
00096         /* acl->first, last = NULL not needed */
00097         return (SMB4ACL_T *)acl;
00098 }
00099 
00100 SMB4ACE_T *smb_add_ace4(SMB4ACL_T *acl, SMB_ACE4PROP_T *prop)
00101 {
00102         SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
00103         TALLOC_CTX *mem_ctx = main_loop_talloc_get();
00104         SMB_ACE4_INT_T *ace;
00105 
00106         ace = (SMB_ACE4_INT_T *)TALLOC_SIZE(mem_ctx, sizeof(SMB_ACE4_INT_T));
00107         if (ace==NULL)
00108         {
00109                 DEBUG(0, ("TALLOC_SIZE failed\n"));
00110                 errno = ENOMEM;
00111                 return NULL;
00112         }
00113         memset(ace, 0, sizeof(SMB_ACE4_INT_T));
00114         ace->magic = SMB_ACE4_INT_MAGIC;
00115         /* ace->next = NULL not needed */
00116         memcpy(&ace->prop, prop, sizeof(SMB_ACE4PROP_T));
00117 
00118         if (aclint->first==NULL)
00119         {
00120                 aclint->first = ace;
00121                 aclint->last = ace;
00122         } else {
00123                 aclint->last->next = (void *)ace;
00124                 aclint->last = ace;
00125         }
00126         aclint->naces++;
00127 
00128         return (SMB4ACE_T *)ace;
00129 }
00130 
00131 SMB_ACE4PROP_T *smb_get_ace4(SMB4ACE_T *ace)
00132 {
00133         SMB_ACE4_INT_T *aceint = get_validated_aceint(ace);
00134         if (aceint==NULL)
00135                 return NULL;
00136 
00137         return &aceint->prop;
00138 }
00139 
00140 SMB4ACE_T *smb_next_ace4(SMB4ACE_T *ace)
00141 {
00142         SMB_ACE4_INT_T *aceint = get_validated_aceint(ace);
00143         if (aceint==NULL)
00144                 return NULL;
00145 
00146         return (SMB4ACE_T *)aceint->next;
00147 }
00148 
00149 SMB4ACE_T *smb_first_ace4(SMB4ACL_T *acl)
00150 {
00151         SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
00152         if (aclint==NULL)
00153                 return NULL;
00154 
00155         return (SMB4ACE_T *)aclint->first;
00156 }
00157 
00158 uint32 smb_get_naces(SMB4ACL_T *acl)
00159 {
00160         SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
00161         if (aclint==NULL)
00162                 return 0;
00163 
00164         return aclint->naces;
00165 }
00166 
00167 static int smbacl4_GetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf)
00168 {
00169         memset(psbuf, 0, sizeof(SMB_STRUCT_STAT));
00170         if (fsp->is_directory || fsp->fh->fd == -1) {
00171                 /* Get the stat struct for the owner info. */
00172                 if (SMB_VFS_STAT(fsp->conn,fsp->fsp_name, psbuf) != 0)
00173                 {
00174                         DEBUG(8, ("SMB_VFS_STAT failed with error %s\n",
00175                                 strerror(errno)));
00176                         return -1;
00177                 }
00178         } else {
00179                 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd, psbuf) != 0)
00180                 {
00181                         DEBUG(8, ("SMB_VFS_FSTAT failed with error %s\n",
00182                                 strerror(errno)));
00183                         return -1;
00184                 }
00185         }
00186 
00187         return 0;
00188 }
00189 
00190 static BOOL smbacl4_nfs42win(SMB4ACL_T *acl, /* in */
00191         DOM_SID *psid_owner, /* in */
00192         DOM_SID *psid_group, /* in */
00193         SEC_ACE **ppnt_ace_list, /* out */
00194         int *pgood_aces /* out */
00195 )
00196 {
00197         SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)acl;
00198         SMB_ACE4_INT_T *aceint;
00199         SEC_ACE *nt_ace_list = NULL;
00200         int good_aces = 0;
00201         TALLOC_CTX *mem_ctx = main_loop_talloc_get();
00202 
00203         DEBUG(10, ("smbacl_nfs42win entered"));
00204 
00205         aclint = get_validated_aclint(acl);
00206         if (aclint==NULL)
00207                 return False;
00208 
00209         if (aclint->naces) {
00210                 nt_ace_list = (SEC_ACE *)TALLOC_SIZE(mem_ctx, aclint->naces * sizeof(SEC_ACE));
00211                 if (nt_ace_list==NULL)
00212                 {
00213                         DEBUG(10, ("talloc error"));
00214                         errno = ENOMEM;
00215                         return False;
00216                 }
00217                 memset(nt_ace_list, 0, aclint->naces * sizeof(SEC_ACE));
00218         } else {
00219                 nt_ace_list = NULL;
00220         }
00221 
00222         for (aceint=aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) {
00223                 SEC_ACCESS mask;
00224                 DOM_SID sid;
00225                 SMB_ACE4PROP_T  *ace = &aceint->prop;
00226 
00227                 DEBUG(10, ("magic: 0x%x, type: %d, iflags: %x, flags: %x, mask: %x, "
00228                         "who: %d\n", aceint->magic, ace->aceType, ace->flags,
00229                         ace->aceFlags, ace->aceMask, ace->who.id));
00230 
00231                 SMB_ASSERT(aceint->magic==SMB_ACE4_INT_MAGIC);
00232 
00233                 if (ace->flags & SMB_ACE4_ID_SPECIAL) {
00234                         switch (ace->who.special_id) {
00235                         case SMB_ACE4_WHO_OWNER:
00236                                 sid_copy(&sid, psid_owner);
00237                                 break;
00238                         case SMB_ACE4_WHO_GROUP:
00239                                 sid_copy(&sid, psid_group);
00240                                 break;
00241                         case SMB_ACE4_WHO_EVERYONE:
00242                                 sid_copy(&sid, &global_sid_World);
00243                                 break;
00244                         default:
00245                                 DEBUG(8, ("invalid special who id %d "
00246                                         "ignored\n", ace->who.special_id));
00247                         }
00248                 } else {
00249                         if (ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
00250                                 gid_to_sid(&sid, ace->who.gid);
00251                         } else {
00252                                 uid_to_sid(&sid, ace->who.uid);
00253                         }
00254                 }
00255                 DEBUG(10, ("mapped %d to %s\n", ace->who.id,
00256                         sid_string_static(&sid)));
00257 
00258                 init_sec_access(&mask, ace->aceMask);
00259                 init_sec_ace(&nt_ace_list[good_aces++], &sid,
00260                         ace->aceType, mask,
00261                         ace->aceFlags & 0xf);
00262         }
00263 
00264         *ppnt_ace_list = nt_ace_list;
00265         *pgood_aces = good_aces;
00266 
00267         return True;
00268 }
00269 
00270 size_t smb_get_nt_acl_nfs4(files_struct *fsp,
00271         uint32 security_info,
00272         SEC_DESC **ppdesc, SMB4ACL_T *acl)
00273 {
00274         int     good_aces = 0;
00275         SMB_STRUCT_STAT sbuf;
00276         DOM_SID sid_owner, sid_group;
00277         size_t sd_size = 0;
00278         SEC_ACE *nt_ace_list = NULL;
00279         SEC_ACL *psa = NULL;
00280         TALLOC_CTX *mem_ctx = main_loop_talloc_get();
00281 
00282         DEBUG(10, ("smb_get_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
00283 
00284         if (acl==NULL || smb_get_naces(acl)==0)
00285                 return 0; /* special because we shouldn't alloc 0 for win */
00286 
00287         if (smbacl4_GetFileOwner(fsp, &sbuf))
00288                 return 0;
00289 
00290         uid_to_sid(&sid_owner, sbuf.st_uid);
00291         gid_to_sid(&sid_group, sbuf.st_gid);
00292 
00293         if (smbacl4_nfs42win(acl,
00294                 &sid_owner,
00295                 &sid_group,
00296                 &nt_ace_list,
00297                 &good_aces
00298                 )==False) {
00299                 DEBUG(8,("smbacl4_nfs42win failed\n"));
00300                 return 0;
00301         }
00302 
00303         psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION,
00304                 good_aces, nt_ace_list);
00305         if (psa == NULL) {
00306                 DEBUG(2,("make_sec_acl failed\n"));
00307                 return 0;
00308         }
00309 
00310         DEBUG(10,("after make sec_acl\n"));
00311         *ppdesc = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
00312                 SEC_DESC_SELF_RELATIVE,
00313                 (security_info & OWNER_SECURITY_INFORMATION)
00314                 ? &sid_owner : NULL,
00315                 (security_info & GROUP_SECURITY_INFORMATION)
00316                 ? &sid_group : NULL,
00317                 NULL, psa, &sd_size);
00318         if (*ppdesc==NULL) {
00319                 DEBUG(2,("make_sec_desc failed\n"));
00320                 return 0;
00321         }
00322 
00323         DEBUG(10, ("smb_get_nt_acl_nfs4 successfully exited with sd_size %d\n", sd_size));
00324         return sd_size;
00325 }
00326 
00327 enum smbacl4_mode_enum {e_simple=0, e_special=1};
00328 enum smbacl4_acedup_enum {e_dontcare=0, e_reject=1, e_ignore=2, e_merge=3};
00329 
00330 typedef struct _smbacl4_vfs_params {
00331         enum smbacl4_mode_enum mode;
00332         BOOL do_chown;
00333         enum smbacl4_acedup_enum acedup;
00334 } smbacl4_vfs_params;
00335 
00336 /*
00337  * Gather special parameters for NFS4 ACL handling
00338  */
00339 static int smbacl4_get_vfs_params(
00340         const char *type_name,
00341         files_struct *fsp,
00342         smbacl4_vfs_params *params
00343 )
00344 {
00345         static const struct enum_list enum_smbacl4_modes[] = {
00346                 { e_simple, "simple" },
00347                 { e_special, "special" }
00348         };
00349         static const struct enum_list enum_smbacl4_acedups[] = {
00350                 { e_dontcare, "dontcare" },
00351                 { e_reject, "reject" },
00352                 { e_ignore, "ignore" },
00353                 { e_merge, "merge" },
00354         };
00355 
00356         memset(params, 0, sizeof(smbacl4_vfs_params));
00357         params->mode = (enum smbacl4_mode_enum)lp_parm_enum(
00358                 SNUM(fsp->conn), type_name,
00359                 "mode", enum_smbacl4_modes, e_simple);
00360         params->do_chown = lp_parm_bool(SNUM(fsp->conn), type_name,
00361                 "chown", True);
00362         params->acedup = (enum smbacl4_acedup_enum)lp_parm_enum(
00363                 SNUM(fsp->conn), type_name,
00364                 "acedup", enum_smbacl4_acedups, e_dontcare);
00365 
00366         DEBUG(10, ("mode:%s, do_chown:%s, acedup: %s\n",
00367                 enum_smbacl4_modes[params->mode].name,
00368                 params->do_chown ? "true" : "false",
00369                 enum_smbacl4_acedups[params->acedup].name));
00370 
00371         return 0;
00372 }
00373 
00374 static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *acl)
00375 {
00376         SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
00377         SMB_ACE4_INT_T *aceint;
00378 
00379         DEBUG(level, ("NFS4ACL: size=%d\n", aclint->naces));
00380 
00381         for(aceint = aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) {
00382                 SMB_ACE4PROP_T *ace = &aceint->prop;
00383 
00384                 DEBUG(level, ("\tACE: type=%d, flags=0x%x, fflags=0x%x, mask=0x%x, id=%d\n",
00385                         ace->aceType,
00386                         ace->aceFlags, ace->flags,
00387                         ace->aceMask,
00388                         ace->who.id));
00389         }
00390 }
00391 
00392 /* 
00393  * Find 2 NFS4 who-special ACE property (non-copy!!!)
00394  * match nonzero if "special" and who is equal
00395  * return ace if found matching; otherwise NULL
00396  */
00397 static SMB_ACE4PROP_T *smbacl4_find_equal_special(
00398         SMB4ACL_T *acl,
00399         SMB_ACE4PROP_T *aceNew)
00400 {
00401         SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
00402         SMB_ACE4_INT_T *aceint;
00403 
00404         for(aceint = aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) {
00405                 SMB_ACE4PROP_T *ace = &aceint->prop;
00406 
00407                 if (ace->flags == aceNew->flags &&
00408                         ace->aceType==aceNew->aceType &&
00409                         (ace->aceFlags&SMB_ACE4_IDENTIFIER_GROUP)==
00410                         (aceNew->aceFlags&SMB_ACE4_IDENTIFIER_GROUP)
00411                 ) {
00412                         /* keep type safety; e.g. gid is an u.short */
00413                         if (ace->flags & SMB_ACE4_ID_SPECIAL)
00414                         {
00415                                 if (ace->who.special_id==aceNew->who.special_id)
00416                                         return ace;
00417                         } else {
00418                                 if (ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP)
00419                                 {
00420                                         if (ace->who.gid==aceNew->who.gid)
00421                                                 return ace;
00422                                 } else {
00423                                         if (ace->who.uid==aceNew->who.uid)
00424                                                 return ace;
00425                                 }
00426                         }
00427                 }
00428         }
00429 
00430         return NULL;
00431 }
00432 
00433 static int smbacl4_fill_ace4(
00434         TALLOC_CTX *mem_ctx,
00435         smbacl4_vfs_params *params,
00436         uid_t ownerUID,
00437         gid_t ownerGID,
00438         SEC_ACE *ace_nt, /* input */
00439         SMB_ACE4PROP_T *ace_v4 /* output */
00440 )
00441 {
00442         const char *dom, *name;
00443         enum lsa_SidType type;
00444         uid_t uid;
00445         gid_t gid;
00446 
00447         DEBUG(10, ("got ace for %s\n",
00448                 sid_string_static(&ace_nt->trustee)));
00449 
00450         memset(ace_v4, 0, sizeof(SMB_ACE4PROP_T));
00451         ace_v4->aceType = ace_nt->type; /* only ACCES|DENY supported right now */
00452         ace_v4->aceFlags = ace_nt->flags & SEC_ACE_FLAG_VALID_INHERIT;
00453         ace_v4->aceMask = ace_nt->access_mask &
00454                 (STD_RIGHT_ALL_ACCESS | SA_RIGHT_FILE_ALL_ACCESS);
00455 
00456         if (ace_v4->aceFlags!=ace_nt->flags)
00457                 DEBUG(9, ("ace_v4->aceFlags(0x%x)!=ace_nt->flags(0x%x)\n",
00458                         ace_v4->aceFlags, ace_nt->flags));
00459 
00460         if (ace_v4->aceMask!=ace_nt->access_mask)
00461                 DEBUG(9, ("ace_v4->aceMask(0x%x)!=ace_nt->access_mask(0x%x)\n",
00462                         ace_v4->aceMask, ace_nt->access_mask));
00463 
00464         if (sid_equal(&ace_nt->trustee, &global_sid_World)) {
00465                 ace_v4->who.special_id = SMB_ACE4_WHO_EVERYONE;
00466                 ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
00467         } else {
00468                 if (!lookup_sid(mem_ctx, &ace_nt->trustee, &dom, &name, &type)) {
00469                         DEBUG(8, ("Could not find %s' type\n",
00470                                 sid_string_static(&ace_nt->trustee)));
00471                         errno = EINVAL;
00472                         return -1;
00473                 }
00474 
00475                 if (type == SID_NAME_USER) {
00476                         if (!sid_to_uid(&ace_nt->trustee, &uid)) {
00477                                 DEBUG(2, ("Could not convert %s to uid\n",
00478                                         sid_string_static(&ace_nt->trustee)));
00479                                 return -1;
00480                         }
00481 
00482                         if (params->mode==e_special && uid==ownerUID) {
00483                                 ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
00484                                 ace_v4->who.special_id = SMB_ACE4_WHO_OWNER;
00485                         } else {
00486                                 ace_v4->who.uid = uid;
00487                         }
00488                 } else { /* else group? - TODO check it... */
00489                         if (!sid_to_gid(&ace_nt->trustee, &gid)) {
00490                                 DEBUG(2, ("Could not convert %s to gid\n",
00491                                         sid_string_static(&ace_nt->trustee)));
00492                                 return -1;
00493                         }
00494                         ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
00495 
00496                         if (params->mode==e_special && gid==ownerGID) {
00497                                 ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
00498                                 ace_v4->who.special_id = SMB_ACE4_WHO_GROUP;
00499                         } else {
00500                                 ace_v4->who.gid = gid;
00501                         }
00502                 }
00503         }
00504 
00505         return 0; /* OK */
00506 }
00507 
00508 static int smbacl4_MergeIgnoreReject(
00509         enum smbacl4_acedup_enum acedup,
00510         SMB4ACL_T *acl, /* may modify it */
00511         SMB_ACE4PROP_T *ace, /* the "new" ACE */
00512         BOOL    *paddNewACE,
00513         int     i
00514 )
00515 {
00516         int     result = 0;
00517         SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(acl, ace);
00518         if (ace4found)
00519         {
00520                 switch(acedup)
00521                 {
00522                 case e_merge: /* "merge" flags */
00523                         *paddNewACE = False;
00524                         ace4found->aceFlags |= ace->aceFlags;
00525                         ace4found->aceMask |= ace->aceMask;
00526                         break;
00527                 case e_ignore: /* leave out this record */
00528                         *paddNewACE = False;
00529                         break;
00530                 case e_reject: /* do an error */
00531                         DEBUG(8, ("ACL rejected by duplicate nt ace#%d\n", i));
00532                         errno = EINVAL; /* SHOULD be set on any _real_ error */
00533                         result = -1;
00534                         break;
00535                 default:
00536                         break;
00537                 }
00538         }
00539         return result;
00540 }
00541 
00542 static SMB4ACL_T *smbacl4_win2nfs4(
00543         SEC_ACL *dacl,
00544         smbacl4_vfs_params *pparams,
00545         uid_t ownerUID,
00546         gid_t ownerGID
00547 )
00548 {
00549         SMB4ACL_T *acl;
00550         uint32  i;
00551         TALLOC_CTX *mem_ctx = main_loop_talloc_get();
00552 
00553         DEBUG(10, ("smbacl4_win2nfs4 invoked\n"));
00554 
00555         acl = smb_create_smb4acl();
00556         if (acl==NULL)
00557                 return NULL;
00558 
00559         for(i=0; i<dacl->num_aces; i++) {
00560                 SMB_ACE4PROP_T  ace_v4;
00561                 BOOL    addNewACE = True;
00562 
00563                 if (smbacl4_fill_ace4(mem_ctx, pparams, ownerUID, ownerGID,
00564                         dacl->aces + i, &ace_v4))
00565                         return NULL;
00566 
00567                 if (pparams->acedup!=e_dontcare) {
00568                         if (smbacl4_MergeIgnoreReject(pparams->acedup, acl,
00569                                 &ace_v4, &addNewACE, i))
00570                                 return NULL;
00571                 }
00572 
00573                 if (addNewACE)
00574                         smb_add_ace4(acl, &ace_v4);
00575         }
00576 
00577         return acl;
00578 }
00579 
00580 BOOL smb_set_nt_acl_nfs4(files_struct *fsp,
00581         uint32 security_info_sent,
00582         SEC_DESC *psd,
00583         set_nfs4acl_native_fn_t set_nfs4_native)
00584 {
00585         smbacl4_vfs_params params;
00586         SMB4ACL_T *acl = NULL;
00587         BOOL    result;
00588 
00589         SMB_STRUCT_STAT sbuf;
00590         BOOL need_chown = False;
00591         uid_t newUID = (uid_t)-1;
00592         gid_t newGID = (gid_t)-1;
00593 
00594         DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
00595 
00596         if ((security_info_sent & (DACL_SECURITY_INFORMATION |
00597                 GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION)) == 0)
00598         {
00599                 DEBUG(9, ("security_info_sent (0x%x) ignored\n",
00600                         security_info_sent));
00601                 return True; /* won't show error - later to be refined... */
00602         }
00603 
00604         /* Special behaviours */
00605         if (smbacl4_get_vfs_params(SMBACL4_PARAM_TYPE_NAME, fsp, &params))
00606                 return False;
00607 
00608         if (smbacl4_GetFileOwner(fsp, &sbuf))
00609                 return False;
00610 
00611         if (params.do_chown) {
00612                 /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */
00613                 if (!unpack_nt_owners(SNUM(fsp->conn), &newUID, &newGID, security_info_sent, psd))
00614                 {
00615                         DEBUG(8, ("unpack_nt_owners failed"));
00616                         return False;
00617                 }
00618                 if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) ||
00619                         ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
00620                         need_chown = True;
00621                 }
00622                 if (need_chown) {
00623                         if ((newUID == (uid_t)-1 || newUID == current_user.ut.uid)) {
00624                                 if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
00625                                         DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
00626                                                 fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) ));
00627                                         return False;
00628                                 }
00629                                 DEBUG(10,("chown %s, %u, %u succeeded.\n",
00630                                         fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
00631                                 if (smbacl4_GetFileOwner(fsp, &sbuf))
00632                                         return False;
00633                                 need_chown = False;
00634                         } else { /* chown is needed, but _after_ changing acl */
00635                                 sbuf.st_uid = newUID; /* OWNER@ in case of e_special */
00636                                 sbuf.st_gid = newGID; /* GROUP@ in case of e_special */
00637                         }
00638                 }
00639         }
00640 
00641         if ((security_info_sent & DACL_SECURITY_INFORMATION)!=0 && psd->dacl!=NULL)
00642         {
00643                 acl = smbacl4_win2nfs4(psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
00644                 if (!acl)
00645                         return False;
00646 
00647                 smbacl4_dump_nfs4acl(10, acl);
00648 
00649                 result = set_nfs4_native(fsp, acl);
00650                 if (result!=True)
00651                 {
00652                         DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno)));
00653                         return False;
00654                 }
00655         } else
00656                 DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent));
00657 
00658         /* Any chown pending? */
00659         if (need_chown) {
00660                 DEBUG(3,("chown#2 %s. uid = %u, gid = %u.\n",
00661                         fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
00662                 if (try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
00663                         DEBUG(2,("chown#2 %s, %u, %u failed. Error = %s.\n",
00664                                 fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
00665                                 strerror(errno)));
00666                         return False;
00667                 }
00668                 DEBUG(10,("chown#2 %s, %u, %u succeeded.\n",
00669                         fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
00670         }
00671 
00672         DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n"));
00673         return True;
00674 }

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