3 * Block access from links to dev mount points specified in PARAMCONF file
5 * Copyright (C) Ronald Kuetemeier, 2001
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <sys/types.h>
50 DIR *block_opendir(struct connection_struct
*conn
, char *fname
);
51 int block_connect(struct connection_struct
*conn
, char *service
, char *user
);
52 void block_disconnect(struct connection_struct
*conn
);
58 extern struct vfs_ops default_vfs_ops
; /* For passthrough operation */
60 struct vfs_ops execute_vfs_ops
= {
68 /* Directory operations */
98 NULL
, /* fget_nt_acl */
99 NULL
, /* get_nt_acl */
100 NULL
, /* fset_nt_acl */
101 NULL
, /* set_nt_acl */
108 #define PARAMCONF "/etc/samba-block.conf"
111 extern BOOL
pm_process(char *FileName
, BOOL (*sfunc
)(char *), BOOL(*pfunc
)(char * , char *));
115 BOOL
enter_pblock_mount(char *dir
);
116 BOOL
get_section(char *sect
);
117 BOOL
get_parameter_value(char *param
, char *value
);
118 BOOL
load_param(void);
119 BOOL
search(struct stat
*stat_buf
);
120 BOOL
dir_search(char *link
, char *dir
);
121 BOOL
enter_pblock_dir(char *dir
);
125 typedef struct block_dir
130 struct block_dir
*next
;
134 static char *params
[] = {"mount_point","dir_name"};
135 enum { MOUNT_POINT
, DIR_NAME
};
137 static struct block_dir
*pblock_mountp
= NULL
;
138 static struct block_dir
*pblock_dir
= NULL
;
143 * Load the conf file into a table
146 BOOL
load_param(void)
149 if ((pm_process(PARAMCONF
,&get_section
,&get_parameter_value
)) == TRUE
)
160 * Enter the key and data into the list
164 BOOL
enter_pblock_mount(char *dir
)
166 struct stat stat_buf
;
167 static struct block_dir
*tmp_pblock
;
170 if((stat(dir
,&stat_buf
)) != 0)
175 if(pblock_mountp
== NULL
)
177 pblock_mountp
= calloc(1, sizeof(block_dir
));
178 if( pblock_mountp
== NULL
)
182 tmp_pblock
= pblock_mountp
;
183 tmp_pblock
->next
= NULL
;
187 tmp_pblock
->next
= calloc(1, sizeof(block_dir
));
188 if(tmp_pblock
->next
== NULL
)
192 tmp_pblock
= tmp_pblock
->next
;
193 tmp_pblock
->next
= NULL
;
198 tmp_pblock
->st_dev
= stat_buf
.st_dev
;
199 tmp_pblock
->dir_name
= strdup(dir
);
208 * Enter the key and data into the list
212 BOOL
enter_pblock_dir(char *dir
)
214 static struct block_dir
*tmp_pblock
;
217 if(pblock_dir
== NULL
)
219 pblock_dir
= calloc(1, sizeof(block_dir
));
220 if( pblock_dir
== NULL
)
224 tmp_pblock
= pblock_dir
;
225 tmp_pblock
->next
= NULL
;
229 tmp_pblock
->next
= calloc(1, sizeof(block_dir
));
230 if(tmp_pblock
->next
== NULL
)
234 tmp_pblock
= tmp_pblock
->next
;
235 tmp_pblock
->next
= NULL
;
240 tmp_pblock
->dir_name
= strdup(dir
);
241 tmp_pblock
->str_len
= strlen(dir
);
252 * Function callback for config section names
255 BOOL
get_section(char *sect
)
263 * Function callback for config parameter value pairs
267 BOOL
get_parameter_value(char *param
, char *value
)
269 int i
= 0, maxargs
= sizeof(params
) / sizeof(char *);
272 for( i
= 0; i
< maxargs
; i
++)
274 if (strcmp(param
,params
[i
]) == 0)
279 enter_pblock_mount(value
);
282 enter_pblock_dir(value
);
297 /* VFS initialisation function. Return initialised vfs_ops structure
300 struct vfs_ops
*vfs_init(int *vfs_version
)
302 *vfs_version
= SMB_VFS_INTERFACE_VERSION
;
304 return(&execute_vfs_ops
);
309 * VFS connect and param file loading
312 int block_connect(struct connection_struct
*conn
, char *service
, char *user
)
314 if((load_param()) == FALSE
)
321 DEBUG(0,("%s connecting \n",conn
->user
));
323 return (default_vfs_ops
.connect(conn
, service
,user
));
327 * Free allocated structures and disconnect
332 void block_disconnect(struct connection_struct
*conn
)
335 struct block_dir
*tmp_pblock
= (pblock_mountp
== NULL
? pblock_dir
: pblock_mountp
);
336 struct block_dir
*free_pblock
= NULL
;
338 while(tmp_pblock
!= NULL
)
340 free(tmp_pblock
->dir_name
);
341 free_pblock
= tmp_pblock
;
342 tmp_pblock
= tmp_pblock
->next
;
345 if(tmp_pblock
== NULL
&& pblock_dir
!= NULL
)
347 tmp_pblock
= (pblock_mountp
== NULL
? pblock_dir
: NULL
);
356 default_vfs_ops
.disconnect(conn
);
363 DIR *block_opendir(struct connection_struct
*conn
, char *fname
)
366 char *dir_name
= NULL
;
367 struct stat stat_buf
;
369 dir_name
= alloca((strlen(conn
->origpath
) + strlen(fname
) + 2) * sizeof(char));
371 pstrcpy(dir_name
,conn
->origpath
);
372 pstrcat(dir_name
, "/");
373 strncat(dir_name
, fname
, strcspn(fname
,"/"));
375 if((lstat(dir_name
,&stat_buf
)) == 0)
377 if((S_ISLNK(stat_buf
.st_mode
)) == 1)
379 stat(dir_name
,&stat_buf
);
380 if((search(&stat_buf
) || dir_search(dir_name
, fname
) ) == TRUE
)
382 DEBUG(0,("%s used link to blocked dir: %s \n", conn
->user
, dir_name
));
389 return (default_vfs_ops
.opendir(conn
, fname
));
394 * Find mount point to block in list
397 BOOL
search(struct stat
*stat_buf
)
399 struct block_dir
*tmp_pblock
= pblock_mountp
;
401 while(tmp_pblock
!= NULL
)
404 if(tmp_pblock
->st_dev
== stat_buf
->st_dev
)
408 tmp_pblock
= tmp_pblock
->next
;
416 * Find dir in list to block id the starting point is link from a share
419 BOOL
dir_search(char *link
, char *dir
)
421 char buf
[PATH_MAX
+1], *ext_path
;
423 struct block_dir
*tmp_pblock
= pblock_dir
;
425 if((len
= readlink(link
,buf
,sizeof(buf
))) == -1)
435 if((ext_path
= strchr(dir
,'/')) != NULL
)
437 pstrcat(buf
,&ext_path
[1]);
441 while(tmp_pblock
!= NULL
)
443 if(len
< tmp_pblock
->str_len
)
445 tmp_pblock
= tmp_pblock
->next
;
449 if((strstr(buf
,tmp_pblock
->dir_name
)) != NULL
)
453 tmp_pblock
= tmp_pblock
->next
;