s3:smbd: add a nfs backend for sysquotas.
[amitay/samba.git] / source3 / lib / sysquotas.c
index 1c5c7e8bd4fbfa6d2c149d03f5913e3caf8039d3..6abafbd768c3542a40d24fd29456d3a156c11659 100644 (file)
@@ -5,7 +5,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 
@@ -61,21 +60,24 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
        (*bdev) = NULL;
        (*fs) = NULL;
        
-       if ( sys_stat(path, &S) == -1 )
+       if ( sys_stat(path, &S, false) == -1 )
                return (-1);
 
-       devno = S.st_dev ;
+       devno = S.st_ex_dev ;
 
        fp = setmntent(MOUNTED,"r");
+       if (fp == NULL) {
+               return -1;
+       }
   
        while ((mnt = getmntent(fp))) {
-               if ( sys_stat(mnt->mnt_dir,&S) == -1 )
+               if ( sys_stat(mnt->mnt_dir, &S, false) == -1 )
                        continue ;
 
-               if (S.st_dev == devno) {
-                       (*mntpath) = strdup(mnt->mnt_dir);
-                       (*bdev) = strdup(mnt->mnt_fsname);
-                       (*fs)   = strdup(mnt->mnt_type);
+               if (S.st_ex_dev == devno) {
+                       (*mntpath) = SMB_STRDUP(mnt->mnt_dir);
+                       (*bdev) = SMB_STRDUP(mnt->mnt_fsname);
+                       (*fs)   = SMB_STRDUP(mnt->mnt_type);
                        if ((*mntpath)&&(*bdev)&&(*fs)) {
                                ret = 0;
                        } else {
@@ -112,11 +114,11 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
        
        /* find the block device file */
 
-       if ((ret=sys_stat(path, &S))!=0) {
+       if ((ret=sys_stat(path, &S, false))!=0) {
                return ret;
        }
        
-       if ((ret=devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1))!=0) {
+       if ((ret=devnm(S_IFBLK, S.st_ex_dev, dev_disk, 256, 1))!=0) {
                return ret;     
        }
 
@@ -124,8 +126,8 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
         * but I don't know how
         * --metze
         */
-       (*mntpath) = strdup(path);
-       (*bdev) = strdup(dev_disk);
+       (*mntpath) = SMB_STRDUP(path);
+       (*bdev) = SMB_STRDUP(dev_disk);
        if ((*mntpath)&&(*bdev)) {
                ret = 0;
        } else {
@@ -152,7 +154,7 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
        (*bdev) = NULL;
        (*fs) = NULL;
        
-       (*mntpath) = strdup(path);
+       (*mntpath) = SMB_STRDUP(path);
        if (*mntpath) {
                ret = 0;
        } else {
@@ -175,19 +177,22 @@ static struct {
 #ifdef HAVE_XFS_QUOTAS
        {"xfs", sys_get_xfs_quota,      sys_set_xfs_quota},
 #endif /* HAVE_XFS_QUOTAS */
-       {NULL,  NULL,                   NULL}   
+#ifdef HAVE_NFS_QUOTAS
+       {"nfs", sys_get_nfs_quota,      sys_set_nfs_quota},
+#endif /* HAVE_NFS_QUOTAS */
+       {NULL,  NULL,                   NULL}
 };
 
 static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
 {
        const char *get_quota_command;
-       
+       char **lines = NULL;
+
        get_quota_command = lp_get_quota_command();
        if (get_quota_command && *get_quota_command) {
                const char *p;
                char *p2;
-               char **lines;
-               pstring syscmd;
+               char *syscmd = NULL;
                int _id = -1;
 
                switch(qtype) {
@@ -204,13 +209,16 @@ static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
                                return -1;
                }
 
-               slprintf(syscmd, sizeof(syscmd)-1, 
-                       "%s \"%s\" %d %d", 
-                       get_quota_command, path, qtype, _id);
+               if (asprintf(&syscmd, "%s \"%s\" %d %d",
+                       get_quota_command, path, qtype, _id) < 0) {
+                       return -1;
+               }
 
                DEBUG (3, ("get_quota: Running command %s\n", syscmd));
 
                lines = file_lines_pload(syscmd, NULL);
+               SAFE_FREE(syscmd);
+
                if (lines) {
                        char *line = lines[0];
 
@@ -220,49 +228,79 @@ static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
 
                        dp->qflags = (enum SMB_QUOTA_TYPE)strtoul(line, &p2, 10);
                        p = p2;
-                       while (p && *p && isspace(*p))
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->curblocks = STR_TO_SMB_BIG_UINT(p, &p);
-                       else 
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->softlimit = STR_TO_SMB_BIG_UINT(p, &p);
-                       else
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->hardlimit = STR_TO_SMB_BIG_UINT(p, &p);
-                       else 
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->curinodes = STR_TO_SMB_BIG_UINT(p, &p);
-                       else
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->isoftlimit = STR_TO_SMB_BIG_UINT(p, &p);
-                       else
+                       } else {
                                goto invalid_param;
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->ihardlimit = STR_TO_SMB_BIG_UINT(p, &p);
-                       else
+                       } else {
                                goto invalid_param;     
-                       while (p && *p && isspace(*p))
+                       }
+
+                       while (p && *p && isspace(*p)) {
                                p++;
-                       if (p && *p)
+                       }
+
+                       if (p && *p) {
                                dp->bsize = STR_TO_SMB_BIG_UINT(p, NULL);
-                       else
+                       } else {
                                dp->bsize = 1024;
-                       file_lines_free(lines);
+                       }
+
+                       TALLOC_FREE(lines);
+                       lines = NULL;
+
                        DEBUG (3, ("Parsed output of get_quota, ...\n"));
 
 #ifdef LARGE_SMB_OFF_T
@@ -293,8 +331,10 @@ static int command_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
 
        errno = ENOSYS;
        return -1;
-       
+
 invalid_param:
+
+       TALLOC_FREE(lines);
        DEBUG(0,("The output of get_quota_command is invalid!\n"));
        return -1;
 }
@@ -302,11 +342,11 @@ invalid_param:
 static int command_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
 {
        const char *set_quota_command;
-       
+
        set_quota_command = lp_set_quota_command();
        if (set_quota_command && *set_quota_command) {
-               char **lines;
-               pstring syscmd;
+               char **lines = NULL;
+               char *syscmd = NULL;
                int _id = -1;
 
                switch(qtype) {
@@ -323,37 +363,40 @@ static int command_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
                }
 
 #ifdef LARGE_SMB_OFF_T
-               slprintf(syscmd, sizeof(syscmd)-1, 
+               if (asprintf(&syscmd,
                        "%s \"%s\" %d %d "
                        "%u %llu %llu "
-                       "%llu %llu %llu ", 
+                       "%llu %llu %llu ",
                        set_quota_command, path, qtype, _id, dp->qflags,
                        (long long unsigned)dp->softlimit,(long long unsigned)dp->hardlimit,
                        (long long unsigned)dp->isoftlimit,(long long unsigned)dp->ihardlimit,
-                       (long long unsigned)dp->bsize);
+                       (long long unsigned)dp->bsize) < 0) {
+                       return -1;
+               }
 #else /* LARGE_SMB_OFF_T */
-               slprintf(syscmd, sizeof(syscmd)-1, 
+               if (asprintf(&syscmd,
                        "%s \"%s\" %d %d "
                        "%u %lu %lu "
-                       "%lu %lu %lu ", 
+                       "%lu %lu %lu ",
                        set_quota_command, path, qtype, _id, dp->qflags,
                        (long unsigned)dp->softlimit,(long unsigned)dp->hardlimit,
                        (long unsigned)dp->isoftlimit,(long unsigned)dp->ihardlimit,
-                       (long unsigned)dp->bsize);
+                       (long unsigned)dp->bsize) < 0) {
+                       return -1;
+               }
 #endif /* LARGE_SMB_OFF_T */
 
-
-
                DEBUG (3, ("get_quota: Running command %s\n", syscmd));
 
                lines = file_lines_pload(syscmd, NULL);
+               SAFE_FREE(syscmd);
                if (lines) {
                        char *line = lines[0];
 
                        DEBUG (3, ("Read output from set_quota, \"%s\"\n", line));
 
-                       file_lines_free(lines);
-                       
+                       TALLOC_FREE(lines);
+
                        return 0;
                }
                DEBUG (0, ("set_quota_command failed!\n"));
@@ -368,7 +411,7 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
 {
        int ret = -1;
        int i;
-       BOOL ready = False;
+       bool ready = False;
        char *mntpath = NULL;
        char *bdev = NULL;
        char *fs = NULL;
@@ -433,7 +476,7 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
 {
        int ret = -1;
        int i;
-       BOOL ready = False;
+       bool ready = False;
        char *mntpath = NULL;
        char *bdev = NULL;
        char *fs = NULL;
@@ -497,6 +540,8 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
 }
 
 #else /* HAVE_SYS_QUOTAS */
+ void dummy_sysquotas_c(void);
+
  void dummy_sysquotas_c(void)
 {
        return;