/[pdpsoft]/trunk/grid-mw-security/cgul/fileutil/fileutil.c
ViewVC logotype

Diff of /trunk/grid-mw-security/cgul/fileutil/fileutil.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1475 by msalle, Mon Feb 8 15:00:23 2010 UTC revision 1476 by msalle, Mon Feb 8 16:11:46 2010 UTC
# Line 6  Line 6 
6  #include <string.h>  #include <string.h>
7    
8  #include "fileutil.h"  #include "fileutil.h"
9    #include "../safefile-1.0/safe_id_range_list.h"
10    #include "../safefile-1.0/safe_is_path_trusted.h"
11    
12  static int priv_drop(uid_t unpriv_uid,gid_t unpriv_gid);  static int priv_drop(uid_t unpriv_uid,gid_t unpriv_gid);
13  static int raise_priv(uid_t euid, gid_t egid);  static int raise_priv(uid_t euid, gid_t egid);
# Line 106  int raise_priv(uid_t euid, gid_t egid) { Line 108  int raise_priv(uid_t euid, gid_t egid) {
108  /**  /**
109   * Reads proxy from *path using given lock_type (see cgul_filelock). It tries to   * Reads proxy from *path using given lock_type (see cgul_filelock). It tries to
110   * drop privilege to real-uid/read_gid. Space needed will be malloc-ed.   * drop privilege to real-uid/read_gid. Space needed will be malloc-ed.
111     * Upon successful completion config contains the contents of path.
112   * Return values:   * Return values:
113   * 0: success   * 0: success
114   * -1: I/O error   * -1: I/O error
# Line 120  int cgul_read_proxy(const char *path, in Line 123  int cgul_read_proxy(const char *path, in
123      struct stat st1,st2,*sptr1,*sptr2,*sptr3;      struct stat st1,st2,*sptr1,*sptr2,*sptr3;
124      uid_t uid=getuid(),euid=geteuid();      uid_t uid=getuid(),euid=geteuid();
125      gid_t egid=getegid();      gid_t egid=getegid();
126      char *buf,*buf_new;      char *buf,*buf_new; /* *proxy will be updated when we know everything is ok */
127      ssize_t size;      ssize_t size;
128        
     /* *proxy will be updated when we know everything is ok */  
     buf=*proxy;  
   
129      /* Drop privilege to real uid and special read group */      /* Drop privilege to real uid and special read group */
130      if (priv_drop(uid,read_gid))      if (priv_drop(uid,read_gid))
131          return -2;          return -2;
132      /* Open file */      /* Open file */
133      if ((fd=open(path,O_RDONLY))==-1)      if ((fd=open(path,O_RDONLY))==-1)   {
134          return -1;          raise_priv(euid,egid); return -1;
135        }
136      /* Lock file */      /* Lock file */
137      if (cgul_filelock(fd,lock_type,LCK_READ))    {      if (cgul_filelock(fd,lock_type,LCK_READ))    {
138          close(fd); return -1;          close(fd); raise_priv(euid,egid); return -1;
139      }      }
140      /* Stat the file before reading:      /* Stat the file before reading:
141       * Need ownership and mode for allowed values, size for malloc */       * Need ownership and mode for allowed values, size for malloc */
142      if (fstat(fd,&st1)) {      if (fstat(fd,&st1)) {
143          close(fd); return -1;          close(fd); raise_priv(euid,egid); return -1;
144      }      }
145      /* Check we own it (only uid) and is unreadable/unwriteable for anyone else      /* Check we own it (only uid) and is unreadable/unwriteable for anyone else
146       * */       * */
147      if ( st1.st_uid!=uid ||      if ( st1.st_uid!=uid ||
148           st1.st_mode & S_IRGRP || st1.st_mode & S_IWGRP ||           st1.st_mode & S_IRGRP || st1.st_mode & S_IWGRP ||
149           st1.st_mode & S_IROTH || st1.st_mode & S_IWOTH )   {           st1.st_mode & S_IROTH || st1.st_mode & S_IWOTH )   {
150          close(fd); return -3;          close(fd); raise_priv(euid,egid); return -3;
151      }      }
152      /* Get expected space */      /* Get expected space */
153      if ( (buf=(char *)malloc(st1.st_size))==NULL)   {      if ( (buf=(char *)malloc(st1.st_size))==NULL)   {
154          close(fd); return -4;          close(fd); raise_priv(euid,egid); return -4;
155      }      }
156      /* use pointers to the two so that we can swap them easily */      /* use pointers to the two so that we can swap them easily */
157      sptr1=&st1; sptr2=&st2;      sptr1=&st1; sptr2=&st2;
# Line 205  int cgul_read_proxy(const char *path, in Line 206  int cgul_read_proxy(const char *path, in
206  }  }
207    
208  /**  /**
209     * Used to read in a config file, the path is checked to be trusted using
210     * safe_is_path_trusted_r() from the safefile library of J. Kupsch.
211     * Upon successful completion config contains the contents of path
212     * Return values:
213     *  0: succes
214     *  -1: I/O error
215     *  -2: privilege-drop error
216     *  -3: permission error (untrusted path)
217     *  -4: memory error
218     *  -5: unknown or safefile error
219     */
220    int cgul_read_config(const char *path, char **config, gid_t read_gid)   {
221        int fd,rc,trust;
222        uid_t uid=getuid(),euid=geteuid();
223        gid_t gid=getgid(),egid=getegid(),target_gid=read_gid<0 ? gid : read_gid;
224        struct safe_id_range_list ulist,glist;
225        struct stat st;
226        char *buf;
227    
228        /* Drop privilege to real uid and special read group */
229        if (priv_drop(uid,read_gid))
230            return -2;
231        /* initialize the lists of trusted uid/gid, can basically only fail when
232         * out of memory */
233        if ( safe_init_id_range_list(&ulist) ||
234             safe_init_id_range_list(&glist) ||
235             safe_add_id_to_list(&ulist,uid) ||
236             safe_add_id_to_list(&glist,target_gid) )  {
237            raise_priv(euid,egid); return -4;
238        }
239        /* Check trust */
240        trust=safe_is_path_trusted_r(path,&ulist,&glist);
241        /* free the range lists */
242        safe_destroy_id_range_list(&ulist);
243        safe_destroy_id_range_list(&glist);
244        /* Check the level of trust */
245        switch (trust)  {
246            case SAFE_PATH_ERROR:
247                raise_priv(euid,egid); return -5; break; /* */
248            case SAFE_PATH_UNTRUSTED:
249            case SAFE_PATH_TRUSTED_STICKY_DIR:
250                raise_priv(euid,egid); return -3; break; /* Perms are somehow wrong */
251            case SAFE_PATH_TRUSTED:
252            case SAFE_PATH_TRUSTED_CONFIDENTIAL:
253                break; /* trusted */
254            default:
255                raise_priv(euid,egid); return -5; break; /* unknown error */
256        }
257        /* Open file and stat the file (latter for size) */
258        if ((fd=open(path,O_RDONLY))==-1 || fstat(fd,&st))  {
259            raise_priv(euid,egid); return -1;
260        }
261        /* Get expected space */
262        if ( (buf=(char *)malloc(st.st_size))==NULL)   {
263            close(fd); raise_priv(euid,egid); return -4;
264        }
265        /* Read the file, check we get right size */
266        if (read(fd,buf,st.st_size)!=st.st_size)
267            /* read error, but don't return yet, we want to free the memory centrally */
268            rc=-1;
269        else
270            rc=0;
271        /* Close file */
272        close(fd);
273        /* reset euid/egid if it was (effective) root. Ignore exit value. */
274        raise_priv(euid,egid);
275        /* finalize */
276        if (rc!=0)
277            free(buf);
278        else /* Only now put buf in *proxy */
279            *config=buf;
280        return rc;
281    }
282    
283    /**
284   * Writes proxy from *proxy to *path using given lock_type (see cgul_filelock).   * Writes proxy from *proxy to *path using given lock_type (see cgul_filelock).
285   * It tries to drop privilege to given write_uid, gid_t write_gid. When either   * It tries to drop privilege to given write_uid, gid_t write_gid. When either
286   * of them is -1, that one is ignored.   * of them is -1, that one is ignored.
# Line 351  int cgul_mkdir_with_parents(const char * Line 427  int cgul_mkdir_with_parents(const char *
427      free(dir);      free(dir);
428      return rc;      return rc;
429  }  }
   
 #if 0  
 /*************************************************************************/  
 /* config read */  
 char *safe_read_file_readonly(char *name)    {  
     drop_priv();  
     fd=fopen(name);  
     st1=fstat(fd); /* 0X00 & owned ? */  
     st2=pathcheck(name); /* -> lstat() */  
     if (st1!=st2)  
         kill;  
     buffer=malloc();  
     read_file(fd,buffer);  
     close();  
     raise_priv();  
     return buffer;  
 }  
 #endif  

Legend:
Removed from v.1475  
changed lines
  Added in v.1476

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28