r3714: Getfacl now seems to work on files and directories. Next do setfacl
authorJeremy Allison <jra@samba.org>
Sat, 13 Nov 2004 00:35:31 +0000 (00:35 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:53:16 +0000 (10:53 -0500)
and port to Samba4.
Jeremy.

source/client/client.c
source/libsmb/clifile.c
source/smbd/trans2.c

index 5644635de7c436e36d0914676eb277086512d42f..29635e4de9fa983be48dbf8b03b243a762ee1d31 100644 (file)
@@ -1788,6 +1788,25 @@ static char *unix_mode_to_str(char *s, mode_t m)
        return s;
 }
 
+/****************************************************************************
+ Utility function for UNIX getfacl.
+****************************************************************************/
+
+static char *perms_to_string(fstring permstr, unsigned char perms)
+{
+       fstrcpy(permstr, "---");
+       if (perms & SMB_POSIX_ACL_READ) {
+               permstr[0] = 'r';
+       }
+       if (perms & SMB_POSIX_ACL_WRITE) {
+               permstr[1] = 'w';
+       }
+       if (perms & SMB_POSIX_ACL_EXECUTE) {
+               permstr[2] = 'x';
+       }
+       return permstr;
+}
+
 /****************************************************************************
  UNIX getfacl.
 ****************************************************************************/
@@ -1798,6 +1817,11 @@ static int cmd_getfacl(void)
        uint16 major, minor;
        uint32 caplow, caphigh;
        char *retbuf = NULL;
+       size_t rb_size = 0;
+       SMB_STRUCT_STAT sbuf;
+       uint16 num_file_acls = 0;
+       uint16 num_dir_acls = 0;
+       uint16 i;
  
        if (!SERVER_HAS_UNIX_CIFS(cli)) {
                d_printf("Server doesn't support UNIX CIFS calls.\n");
@@ -1823,14 +1847,120 @@ static int cmd_getfacl(void)
 
        pstrcat(src,name);
 
-       if (!cli_unix_getfacl(cli, src, &retbuf)) {
+       if (!cli_unix_stat(cli, src, &sbuf)) {
+               d_printf("%s getfacl doing a stat on file %s\n",
+                       cli_errstr(cli), src);
+               return 1;
+       } 
+
+       if (!cli_unix_getfacl(cli, src, &rb_size, &retbuf)) {
                d_printf("%s getfacl file %s\n",
                        cli_errstr(cli), src);
                return 1;
        } 
 
        /* ToDo : Print out the ACL values. */
-       SAFE_FREE(retbuf);      
+       if (SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION || rb_size < 6) {
+               d_printf("getfacl file %s, unknown POSIX acl version %u.\n",
+                       src, (unsigned int)CVAL(retbuf,0) );
+               SAFE_FREE(retbuf);
+               return 1;
+       }
+
+       num_file_acls = SVAL(retbuf,2);
+       num_dir_acls = SVAL(retbuf,4);
+       if (rb_size != SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)) {
+               d_printf("getfacl file %s, incorrect POSIX acl buffer size (should be %u, was %u).\n",
+                       src,
+                       (unsigned int)(SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)),
+                       (unsigned int)rb_size);
+
+               SAFE_FREE(retbuf);
+               return 1;
+       }
+
+       d_printf("# file: %s\n", src);
+       d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid);
+
+       if (num_file_acls == 0 && num_dir_acls == 0) {
+               d_printf("No acls found.\n");
+       }
+
+       for (i = 0; i < num_file_acls; i++) {
+               uint32 uorg;
+               fstring permstring;
+               unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE));
+               unsigned char perms = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+1);
+
+               switch(tagtype) {
+                       case SMB_POSIX_ACL_USER_OBJ:
+                               d_printf("user::");
+                               break;
+                       case SMB_POSIX_ACL_USER:
+                               uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+                               d_printf("user:%u:", uorg);
+                               break;
+                       case SMB_POSIX_ACL_GROUP_OBJ:
+                               d_printf("group::");
+                               break;
+                       case SMB_POSIX_ACL_GROUP:
+                               uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+                               d_printf("group:%u", uorg);
+                               break;
+                       case SMB_POSIX_ACL_MASK:
+                               d_printf("mask::");
+                               break;
+                       case SMB_POSIX_ACL_OTHER:
+                               d_printf("other::");
+                               break;
+                       default:
+                               d_printf("getfacl file %s, incorrect POSIX acl tagtype (%u).\n",
+                                       src, (unsigned int)tagtype );
+                               SAFE_FREE(retbuf);
+                               return 1;
+               }
+
+               d_printf("%s\n", perms_to_string(permstring, perms));
+       }
+
+       for (i = 0; i < num_dir_acls; i++) {
+               uint32 uorg;
+               fstring permstring;
+               unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE));
+               unsigned char perms = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+1);
+
+               switch(tagtype) {
+                       case SMB_POSIX_ACL_USER_OBJ:
+                               d_printf("default:user::");
+                               break;
+                       case SMB_POSIX_ACL_USER:
+                               uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+                               d_printf("default:user:%u:", uorg);
+                               break;
+                       case SMB_POSIX_ACL_GROUP_OBJ:
+                               d_printf("default:group::");
+                               break;
+                       case SMB_POSIX_ACL_GROUP:
+                               uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+                               d_printf("default:group:%u", uorg);
+                               break;
+                       case SMB_POSIX_ACL_MASK:
+                               d_printf("default:mask::");
+                               break;
+                       case SMB_POSIX_ACL_OTHER:
+                               d_printf("default:other::");
+                               break;
+                       default:
+                               d_printf("getfacl file %s, incorrect POSIX acl tagtype (%u).\n",
+                                       src, (unsigned int)tagtype );
+                               SAFE_FREE(retbuf);
+                               return 1;
+               }
+
+               d_printf("%s\n", perms_to_string(permstring, perms));
+       }
+
+       SAFE_FREE(retbuf);
        return 0;
 }
 
index b616abd4d2d708e86c1dc00558b6fe381d13f9ba..7816ed0fc6e57583baef3f229dbe37834df3286a 100644 (file)
@@ -171,7 +171,7 @@ static mode_t unix_filetype_from_wire(uint32 wire_type)
  Do a POSIX getfacl (UNIX extensions).
 ****************************************************************************/
 
-BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, char **retbuf)
+BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf)
 {
        unsigned int param_len = 0;
        unsigned int data_len = 0;
@@ -211,6 +211,7 @@ BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, char **retbuf)
 
        SAFE_FREE(rparam);
        *retbuf = rdata;
+       *prb_size = (size_t)data_len;
 
        return True;
 }
index a12922721566da2f963a45f7158eb1f1ad80ea5c..c401ae5722b97dd98457eebccd078bd3fb58749f 100644 (file)
@@ -2354,6 +2354,7 @@ static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_
                                DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
                                return False;
                }
+               pdata += SMB_POSIX_ACL_ENTRY_SIZE;
        }
 
        return True;