Thread: Directory permissions during creation

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    Directory permissions during creation

    I can successfully create the directory but as soon as I try to create files within the directory it goes pear shaped, someone take a look and tell me what I'm doing wrong
    Code:
    		path = calloc( size, 1 );
    		if ( path ) {
    			sprintf( path, "%s/.gasp", HOME );
    			if ( access(path,0) != 0 && mkdir(path,0666) != 0 )
    				error_cb( "access & mkdir()", (ret = errno), path );
    			sprintf( path, "%s/.gasp/test.aobscan", HOME );
    			if ( (into = creat(path, O_CREAT | O_RDWR )) < 0 )
    				error_cb( "creat()", (ret = errno), path );
    			free(path);
    		}

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Never mind found it, apparently I had to set execution permission, I'm using 0755 now

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The second argument to creat is the mode, not file creation flags.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    "pear shaped"?

    When creating directories, the 'x' permission have a different meaning than for files: They mean 'search', meaning if you don't set this permission, you'll not be able to 'search' through the directory... So, to create a file there you must set 'x' permission as well... Your mkdir() call should be:
    Code:
     ... mkdir( path, 0777 ) ...
    Notice mkdir() - as many libc functions - will set errno in case of error. One better code when creating a directory:
    Code:
    errno = 0;
    if ( mkdir( path, 0777 ) )
    {
      perror( "mkdir" );
      abort();
    }
    Second: Your call to creat() is wrong. Here's the prototype:
    Code:
    int creat( const char *pathname, mode_t mode );
    You should use:
    Code:
     ... creat( path, 0640 ) ...
    if you want your file writable just to the owner and readable to the group.

    Here's an example:
    Code:
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    int main( void )
    {
      int fd;
    
      if ( mkdir( "mydir", 0666 ) )
      {
          perror( "mkdir" );
          return EXIT_FAILURE;
      }
    
      fd = creat( "mydir/file", 0640 );
      if ( fd < 0 )
      {
          perror( "creat" );
          return EXIT_FAILURE;
      }
    
      close( fd );
      return EXIT_SUCCESS;
    }
    Compiling and running:
    Code:
    $ cc -o test test.c
    $ ./test
    creat: Permission denied
    $ rmdir mydir
    $ sed -i 's/0666/0777/' test.c
    $ cc -o test test.c
    $ ./test
    $ tree -p .
    .
    ├── [drwxr-xr-x]  mydir
    │   └── [-rw-r-----]  file
    ├── [-rwxr-xr-x]  test
    └── [-rw-r--r--]  test.c
    BUT... Notice your process is bound to umask from your session. If you take a look at the directory and the file, will notice the 'group' and 'others' permission aren't what you expected, sometimes... Set the umask (with umask() call) beforehand if you want to make sure...
    Last edited by flp1969; 01-24-2020 at 05:50 AM.

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by laserlight View Post
    The second argument to creat is the mode, not file creation flags.
    Didn't even notice, thanks

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by flp1969 View Post
    "pear shaped"?

    When creating directories, the 'x' permission have a different meaning than for files: They mean 'search', meaning if you don't set this permission, you'll not be able to 'search' through the directory... So, to create a file there you must set 'x' permission as well... Your mkdir() call should be:
    Code:
     ... mkdir( path, 0777 ) ...
    Notice mkdir() - as many libc functions - will set errno in case of error. One better code when creating a directory:
    Code:
    errno = 0;
    if ( mkdir( path, 0777 ) )
    {
      perror( "mkdir" );
      abort();
    }
    Second: Your call to creat() is wrong. Here's the prototype:
    Code:
    int creat( const char *pathname, mode_t mode );
    You should use:
    Code:
     ... creat( path, 0640 ) ...
    if you want your file writable just to the owner and readable to the group.

    Here's an example:
    Code:
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    int main( void )
    {
      int fd;
    
      if ( mkdir( "mydir", 0666 ) )
      {
          perror( "mkdir" );
          return EXIT_FAILURE;
      }
    
      fd = creat( "mydir/file", 0640 );
      if ( fd < 0 )
      {
          perror( "creat" );
          return EXIT_FAILURE;
      }
    
      close( fd );
      return EXIT_SUCCESS;
    }
    Compiling and running:
    Code:
    $ cc -o test test.c
    $ ./test
    creat: Permission denied
    $ rmdir mydir
    $ sed -i 's/0666/0777/' test.c
    $ cc -o test test.c
    $ ./test
    $ tree -p .
    .
    ├── [drwxr-xr-x]  mydir
    │   └── [-rw-r-----]  file
    ├── [-rwxr-xr-x]  test
    └── [-rw-r--r--]  test.c
    BUT... Notice your process is bound to umask from your session. If you take a look at the directory and the file, will notice the 'group' and 'others' permission aren't what you expected, sometimes... Set the umask (with umask() call) beforehand if you want to make sure...
    That whole umask thing is fine, it's going in user directory anyways so it should follow user permissions, modified my call for creat to open, now I'm getting IO errors when I attempt to read from a separate descriptor:
    Code:
    	sprintf( path, "/proc/%d/mem", pid);
    	if ( (handle->rdMemFd = open(path,O_RDONLY)) < 0 ) {
    		free(handle);
    		if ( err ) *err = errno;
    		return NULL;
    	}
    	handle->wrMemFd = open(path,O_WRONLY);
    	return handle;
    ...
    	done = upto - from;
    	if ( done >= BUFSIZ ) done = BUFSIZ;
    	if ( (done = read( handle->rdMemFd, buff, done )) < 0 ) {
    		if ( err ) *err = errno;
    		return 0;
    	}
    Yes I have checked later what the FDs are and both are valid (since I'm currently using the current instance of gasp to test on) so I can only think I opened it wrong, any ideas?

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Just tried the pread variant, did not help, gotta go to work now so by for now

  8. #8
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by awsdert View Post
    Yes I have checked later what the FDs are and both are valid (since I'm currently using the current instance of gasp to test on) so I can only think I opened it wrong, any ideas?
    /proc/[pid]/mem requires PTRACE permissions, as told in the manpage:

    Code:
           /proc/[pid]/mem
                  This file can be used to access the pages of a process's memory through
                  open(2), read(2), and lseek(2).
    
                  Permission to access this file is governed by a ptrace access mode 
                  PTRACE_MODE_ATTACH_FSCREDS check; see ptrace(2)

  9. #9
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by flp1969 View Post
    /proc/[pid]/mem requires PTRACE permissions, as told in the manpage:

    Code:
           /proc/[pid]/mem
                  This file can be used to access the pages of a process's memory through
                  open(2), read(2), and lseek(2).
    
                  Permission to access this file is governed by a ptrace access mode 
                  PTRACE_MODE_ATTACH_FSCREDS check; see ptrace(2)
    Thanks, just can't seem to find the function I'm meant to retrieve that permission with, about to start work, could someone post an example of getting that permission, I can try when I get home then

  10. #10
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Well for now I'm utilizing PTRACE_SEIZE and PTRACE_TRACEME to grab permissions, still gotta find a way to gain sudo permissions from in the app with GUI permissions as well, don't understand why gksu and co won't permit GUI apps to be run with root permissions despite the user authorizing them in the 1st place, there's no point asking for a password if it then penalizes it just for makes things more user friendly, that's backward thinking in my opinion.

    Edit: Forgot to mention part of the reason for IO issues turned out to be because I apparently can't just read from point 0 and have to read from /proc/pid/maps file, to resolve that I added an fd and made a quick fix for finding next available address:
    Code:
    intptr_t proc_intptr_next( int *err, proc_handle_t *handle, intptr_t addr, intptr_t *size ) {
    	char line[PAGE_LINE_SIZE] = {0};
    	intptr_t from = 0, upto = 0;
    	if ( !size ) {
    		if ( err ) *err = EDESTADDRREQ;
    		return -1;
    	}
    	*size = -1;
    	if ( !handle ) {
    		if ( err ) *err = EINVAL;
    		return -1;
    	}
    #ifdef _LARGEFILE64_SOURCE
    	lseek64( handle->pagesFd, 0, SEEK_SET );
    #else
    	lseek( handle->pagesFd, 0, SEEK_SET );
    #endif
    	next_page:
    	if ( read( handle->pagesFd, line, PAGE_LINE_SIZE )
    		!= PAGE_LINE_SIZE ) {
    		if ( err ) *err = errno;
    		return -1;
    	}
    	line[PAGE_LINE_SIZE-1] = 0;
    	sscanf( line, "%p-%p", (void**)(&from), (void**)(&upto) );
    	if ( addr >= upto ) {
    		while ( read( handle->pagesFd, line, 1 ) != 1 ) {
    			if ( line[0] == '\n' )
    				goto next_page;
    		}
    		if ( err ) *err = errno;
    		return -1;
    	}
    	*size = upto - from;
    	return from;
    }
    Gotta go to sleep now since have work 2mw
    Last edited by awsdert; 01-24-2020 at 06:30 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Folder Permissions
    By MRIce in forum C Programming
    Replies: 3
    Last Post: 06-25-2012, 01:39 PM
  2. Replies: 6
    Last Post: 04-30-2010, 06:13 PM
  3. Replies: 2
    Last Post: 12-16-2008, 02:43 PM
  4. Directory Creation in C++
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 04-22-2002, 12:17 PM

Tags for this Thread