2008-05-08 13:23:38 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
2006-02-04 01:19:41 +03:00
Copyright ( C ) Jeremy Allison ( jra @ samba . org ) 2005
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-02-04 01:19:41 +03:00
( at your option ) any later version .
2008-05-08 13:23:38 +04:00
2006-02-04 01:19:41 +03:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2008-05-08 13:23:38 +04:00
2006-02-04 01:19:41 +03:00
You should have received a copy of the GNU General Public License
2008-05-10 01:22:12 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2006-02-04 01:19:41 +03:00
# include "includes.h"
2011-02-25 19:14:22 +03:00
# include "system/passwd.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2006-02-04 01:19:41 +03:00
# include "utils/net.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2020-08-07 21:17:34 +03:00
# include "lib/util/string_wrappers.h"
2006-02-04 01:19:41 +03:00
struct {
const char * us_errstr ;
enum usershare_err us_err ;
} us_errs [ ] = {
{ " " , USERSHARE_OK } ,
2009-08-11 10:57:01 +04:00
{ N_ ( " Malformed usershare file " ) , USERSHARE_MALFORMED_FILE } ,
{ N_ ( " Bad version number " ) , USERSHARE_BAD_VERSION } ,
{ N_ ( " Malformed path entry " ) , USERSHARE_MALFORMED_PATH } ,
{ N_ ( " Malformed comment entryfile " ) , USERSHARE_MALFORMED_COMMENT_DEF } ,
{ N_ ( " Malformed acl definition " ) , USERSHARE_MALFORMED_ACL_DEF } ,
{ N_ ( " Acl parse error " ) , USERSHARE_ACL_ERR } ,
{ N_ ( " Path not absolute " ) , USERSHARE_PATH_NOT_ABSOLUTE } ,
{ N_ ( " Path is denied " ) , USERSHARE_PATH_IS_DENIED } ,
{ N_ ( " Path not allowed " ) , USERSHARE_PATH_NOT_ALLOWED } ,
{ N_ ( " Path is not a directory " ) , USERSHARE_PATH_NOT_DIRECTORY } ,
{ N_ ( " System error " ) , USERSHARE_POSIX_ERR } ,
2010-03-27 03:09:58 +03:00
{ N_ ( " Malformed sharename definition " ) , USERSHARE_MALFORMED_SHARENAME_DEF } ,
{ N_ ( " Bad sharename (doesn't match filename) " ) , USERSHARE_BAD_SHARENAME } ,
2006-02-04 01:19:41 +03:00
{ NULL , ( enum usershare_err ) - 1 }
} ;
static const char * get_us_error_code ( enum usershare_err us_err )
{
2007-11-24 18:32:38 +03:00
char * result ;
2006-02-04 01:19:41 +03:00
int idx = 0 ;
while ( us_errs [ idx ] . us_errstr ! = NULL ) {
if ( us_errs [ idx ] . us_err = = us_err ) {
return us_errs [ idx ] . us_errstr ;
}
idx + + ;
}
2009-08-11 10:57:01 +04:00
result = talloc_asprintf ( talloc_tos ( ) , _ ( " Usershare error code (0x%x) " ) ,
2007-11-24 18:32:38 +03:00
( unsigned int ) us_err ) ;
SMB_ASSERT ( result ! = NULL ) ;
return result ;
2006-02-04 01:19:41 +03:00
}
/* The help subsystem for the USERSHARE subcommand */
2008-05-10 01:22:12 +04:00
static int net_usershare_add_usage ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
2008-05-10 01:22:12 +04:00
char chr = * lp_winbind_separator ( ) ;
2009-08-11 10:57:01 +04:00
d_printf ( _ (
2006-04-30 04:36:26 +04:00
" net usershare add [-l|--long] <sharename> <path> [<comment>] [<acl>] [<guest_ok=[y|n]>] \n "
2006-02-04 01:19:41 +03:00
" \t Adds the specified share name for this user. \n "
" \t <sharename> is the new share name. \n "
" \t <path> is the path on the filesystem to export. \n "
" \t <comment> is the optional comment for the new share. \n "
" \t <acl> is an optional share acl in the format \" DOMAIN%cname:X,DOMAIN%cname:X,.... \" \n "
2006-04-30 04:36:26 +04:00
" \t <guest_ok=y> if present sets \" guest ok = yes \" on this usershare. \n "
2006-02-04 01:19:41 +03:00
" \t \t \" X \" represents a permission and can be any one of the characters f, r or d \n "
" \t \t where \" f \" means full control, \" r \" means read-only, \" d \" means deny access. \n "
" \t \t name may be a domain user or group. For local users use the local server name "
" instead of \" DOMAIN \" \n "
" \t \t The default acl is \" Everyone:r \" which allows everyone read-only access. \n "
2009-08-11 10:57:01 +04:00
" \t Add -l or --long to print the info on the newly added share. \n " ) ,
2008-05-10 01:22:12 +04:00
chr , chr ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2008-05-10 01:22:12 +04:00
static int net_usershare_delete_usage ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
2009-08-11 10:57:01 +04:00
d_printf ( _ (
2008-05-19 18:36:18 +04:00
" net usershare delete <sharename> \n "
2009-08-11 10:57:01 +04:00
" \t deletes the specified share name for this user. \n " ) ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2008-05-10 01:22:12 +04:00
static int net_usershare_info_usage ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
2009-08-11 10:57:01 +04:00
d_printf ( _ (
2008-05-19 18:36:18 +04:00
" net usershare info [-l|--long] [wildcard sharename] \n "
2006-02-04 01:19:41 +03:00
" \t Prints out the path, comment and acl elements of shares that match the wildcard. \n "
" \t By default only gives info on shares owned by the current user \n "
" \t Add -l or --long to apply this to all shares \n "
2009-08-11 10:57:01 +04:00
" \t Omit the sharename or use a wildcard of '*' to see all shares \n " ) ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2008-05-10 01:22:12 +04:00
static int net_usershare_list_usage ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
2009-08-11 10:57:01 +04:00
d_printf ( _ (
2008-05-19 18:36:18 +04:00
" net usershare list [-l|--long] [wildcard sharename] \n "
2006-02-04 01:19:41 +03:00
" \t Lists the names of all shares that match the wildcard. \n "
" \t By default only lists shares owned by the current user \n "
" \t Add -l or --long to apply this to all shares \n "
2009-08-11 10:57:01 +04:00
" \t Omit the sharename or use a wildcard of '*' to see all shares \n " ) ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2008-05-10 01:22:12 +04:00
int net_usershare_usage ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
2009-08-11 10:57:01 +04:00
d_printf ( _ ( " net usershare add <sharename> <path> [<comment>] [<acl>] [<guest_ok=[y|n]>] to "
2006-04-30 04:36:26 +04:00
" add or change a user defined share. \n "
2006-02-04 01:19:41 +03:00
" net usershare delete <sharename> to delete a user defined share. \n "
" net usershare info [-l|--long] [wildcard sharename] to print info about a user defined share. \n "
" net usershare list [-l|--long] [wildcard sharename] to list user defined shares. \n "
2008-05-19 18:36:18 +04:00
" net usershare help \n "
2009-08-11 10:57:01 +04:00
" \n Type \" net usershare help <option> \" to get more information on that option \n \n " ) ) ;
2006-02-04 01:19:41 +03:00
2008-05-10 01:22:12 +04:00
net_common_flags_usage ( c , argc , argv ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-04 06:19:19 +03:00
static char * get_basepath ( TALLOC_CTX * ctx )
2006-02-04 01:19:41 +03:00
{
2019-11-05 14:14:37 +03:00
const struct loadparm_substitution * lp_sub =
loadparm_s3_global_substitution ( ) ;
char * basepath = lp_usershare_path ( ctx , lp_sub ) ;
2007-12-04 06:19:19 +03:00
if ( ! basepath ) {
return NULL ;
}
2006-06-15 15:24:01 +04:00
if ( ( basepath [ 0 ] ! = ' \0 ' ) & & ( basepath [ strlen ( basepath ) - 1 ] = = ' / ' ) ) {
2006-02-04 01:19:41 +03:00
basepath [ strlen ( basepath ) - 1 ] = ' \0 ' ;
}
2007-12-04 06:19:19 +03:00
return basepath ;
2006-02-04 01:19:41 +03:00
}
/***************************************************************************
Delete a single userlevel share .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static int net_usershare_delete ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
2019-11-05 14:14:37 +03:00
const struct loadparm_substitution * lp_sub =
loadparm_s3_global_substitution ( ) ;
2007-12-04 06:19:19 +03:00
char * us_path ;
2006-02-04 01:19:41 +03:00
char * sharename ;
2008-05-19 18:36:18 +04:00
if ( argc ! = 1 | | c - > display_usage ) {
2008-05-10 01:22:12 +04:00
return net_usershare_delete_usage ( c , argc , argv ) ;
2006-02-04 01:19:41 +03:00
}
2009-03-19 04:20:11 +03:00
if ( ( sharename = strlower_talloc ( talloc_tos ( ) , argv [ 0 ] ) ) = = NULL ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " strlower_talloc failed \n " ) ) ;
2006-06-19 23:07:39 +04:00
return - 1 ;
}
2006-02-04 01:19:41 +03:00
if ( ! validate_net_name ( sharename , INVALID_SHARENAME_CHARS , strlen ( sharename ) ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " net usershare delete: share name %s contains "
" invalid characters (any of %s) \n " ) ,
2006-02-04 01:19:41 +03:00
sharename , INVALID_SHARENAME_CHARS ) ;
2009-07-15 11:37:04 +04:00
TALLOC_FREE ( sharename ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2007-12-04 06:19:19 +03:00
us_path = talloc_asprintf ( talloc_tos ( ) ,
" %s/%s " ,
2019-11-05 14:14:37 +03:00
lp_usershare_path ( talloc_tos ( ) , lp_sub ) ,
2007-12-04 06:19:19 +03:00
sharename ) ;
if ( ! us_path ) {
2009-07-15 11:37:04 +04:00
TALLOC_FREE ( sharename ) ;
2007-12-04 06:19:19 +03:00
return - 1 ;
}
2006-02-04 01:19:41 +03:00
if ( unlink ( us_path ) ! = 0 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " net usershare delete: unable to remove usershare %s. "
" Error was %s \n " ) ,
2006-02-04 01:19:41 +03:00
us_path , strerror ( errno ) ) ;
2009-07-15 11:37:04 +04:00
TALLOC_FREE ( sharename ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2009-07-15 11:37:04 +04:00
TALLOC_FREE ( sharename ) ;
2006-02-04 01:19:41 +03:00
return 0 ;
}
/***************************************************************************
Data structures to handle a list of usershare files .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct file_list {
struct file_list * next , * prev ;
const char * pathname ;
} ;
static struct file_list * flist ;
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static int get_share_list ( TALLOC_CTX * ctx , const char * wcard , bool only_ours )
2006-02-04 01:19:41 +03:00
{
2012-03-28 06:22:03 +04:00
DIR * dp ;
2012-03-28 06:18:14 +04:00
struct dirent * de ;
2006-02-04 01:19:41 +03:00
uid_t myuid = geteuid ( ) ;
struct file_list * fl = NULL ;
2007-12-04 06:19:19 +03:00
char * basepath = get_basepath ( ctx ) ;
2006-02-04 01:19:41 +03:00
2007-12-04 06:19:19 +03:00
if ( ! basepath ) {
return - 1 ;
}
2012-03-28 06:01:19 +04:00
dp = opendir ( basepath ) ;
2006-02-04 01:19:41 +03:00
if ( ! dp ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " get_share_list: cannot open usershare directory %s. "
" Error %s \n " ) ,
2006-02-04 01:19:41 +03:00
basepath , strerror ( errno ) ) ;
return - 1 ;
}
2012-03-28 06:03:00 +04:00
while ( ( de = readdir ( dp ) ) ! = 0 ) {
2006-02-04 01:19:41 +03:00
SMB_STRUCT_STAT sbuf ;
2007-12-04 06:19:19 +03:00
char * path ;
2006-02-04 01:19:41 +03:00
const char * n = de - > d_name ;
/* Ignore . and .. */
if ( * n = = ' . ' ) {
if ( ( n [ 1 ] = = ' \0 ' ) | | ( n [ 1 ] = = ' . ' & & n [ 2 ] = = ' \0 ' ) ) {
continue ;
}
}
if ( ! validate_net_name ( n , INVALID_SHARENAME_CHARS , strlen ( n ) ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " get_share_list: ignoring bad share "
" name %s \n " ) , n ) ;
2006-02-04 01:19:41 +03:00
continue ;
}
2007-12-04 06:19:19 +03:00
path = talloc_asprintf ( ctx ,
" %s/%s " ,
basepath ,
n ) ;
if ( ! path ) {
2012-03-28 06:08:27 +04:00
closedir ( dp ) ;
2007-12-04 06:19:19 +03:00
return - 1 ;
}
2006-02-04 01:19:41 +03:00
2009-11-27 15:00:51 +03:00
if ( sys_lstat ( path , & sbuf , false ) ! = 0 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " get_share_list: can't lstat file %s. Error "
" was %s \n " ) ,
2006-02-04 01:19:41 +03:00
path , strerror ( errno ) ) ;
continue ;
}
2009-05-14 17:34:42 +04:00
if ( ! S_ISREG ( sbuf . st_ex_mode ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " get_share_list: file %s is not a regular "
" file. Ignoring. \n " ) ,
2006-02-04 01:19:41 +03:00
path ) ;
continue ;
}
2009-05-14 17:34:42 +04:00
if ( only_ours & & sbuf . st_ex_uid ! = myuid ) {
2006-02-04 01:19:41 +03:00
continue ;
}
if ( ! unix_wild_match ( wcard , n ) ) {
continue ;
}
2007-12-04 06:19:19 +03:00
/* (Finally) - add to list. */
2011-06-07 05:38:41 +04:00
fl = talloc ( ctx , struct file_list ) ;
2006-02-04 01:19:41 +03:00
if ( ! fl ) {
2012-03-28 06:08:27 +04:00
closedir ( dp ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
fl - > pathname = talloc_strdup ( ctx , n ) ;
if ( ! fl - > pathname ) {
2012-03-28 06:08:27 +04:00
closedir ( dp ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
DLIST_ADD ( flist , fl ) ;
}
2012-03-28 06:08:27 +04:00
closedir ( dp ) ;
2006-02-04 01:19:41 +03:00
return 0 ;
}
2006-06-16 22:50:01 +04:00
enum us_priv_op { US_LIST_OP , US_INFO_OP } ;
2006-02-04 01:19:41 +03:00
2006-06-16 22:50:01 +04:00
struct us_priv_info {
2006-02-04 01:19:41 +03:00
TALLOC_CTX * ctx ;
2006-06-16 22:50:01 +04:00
enum us_priv_op op ;
2008-05-10 01:22:12 +04:00
struct net_context * c ;
2006-02-04 01:19:41 +03:00
} ;
/***************************************************************************
Call a function for every share on the list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-06 21:03:57 +03:00
static int process_share_list ( int ( * fn ) ( struct file_list * , void * ) , void * priv )
2006-02-04 01:19:41 +03:00
{
struct file_list * fl ;
int ret = 0 ;
for ( fl = flist ; fl ; fl = fl - > next ) {
2006-02-06 21:03:57 +03:00
ret = ( * fn ) ( fl , priv ) ;
2006-02-04 01:19:41 +03:00
}
return ret ;
}
/***************************************************************************
Info function .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-06 21:03:57 +03:00
static int info_fn ( struct file_list * fl , void * priv )
2006-02-04 01:19:41 +03:00
{
SMB_STRUCT_STAT sbuf ;
char * * lines = NULL ;
2006-06-16 22:50:01 +04:00
struct us_priv_info * pi = ( struct us_priv_info * ) priv ;
2006-02-04 01:19:41 +03:00
TALLOC_CTX * ctx = pi - > ctx ;
2008-05-10 01:22:12 +04:00
struct net_context * c = pi - > c ;
2006-02-04 01:19:41 +03:00
int fd = - 1 ;
int numlines = 0 ;
2010-05-18 12:29:34 +04:00
struct security_descriptor * psd = NULL ;
2007-12-04 06:19:19 +03:00
char * basepath ;
2007-11-14 05:42:42 +03:00
char * sharepath = NULL ;
char * comment = NULL ;
2010-03-27 03:09:58 +03:00
char * cp_sharename = NULL ;
2007-12-04 06:19:19 +03:00
char * acl_str ;
2006-02-04 01:19:41 +03:00
int num_aces ;
char sep_str [ 2 ] ;
enum usershare_err us_err ;
2008-05-12 13:53:23 +04:00
bool guest_ok = false ;
2006-02-04 01:19:41 +03:00
sep_str [ 0 ] = * lp_winbind_separator ( ) ;
sep_str [ 1 ] = ' \0 ' ;
2007-12-04 06:19:19 +03:00
basepath = get_basepath ( ctx ) ;
if ( ! basepath ) {
return - 1 ;
}
basepath = talloc_asprintf_append ( basepath ,
" /%s " ,
fl - > pathname ) ;
if ( ! basepath ) {
return - 1 ;
}
2006-02-04 01:19:41 +03:00
# ifdef O_NOFOLLOW
2012-03-28 05:48:00 +04:00
fd = open ( basepath , O_RDONLY | O_NOFOLLOW , 0 ) ;
2006-02-04 01:19:41 +03:00
# else
2012-03-28 05:48:00 +04:00
fd = open ( basepath , O_RDONLY , 0 ) ;
2006-02-04 01:19:41 +03:00
# endif
if ( fd = = - 1 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " info_fn: unable to open %s. %s \n " ) ,
2006-02-04 01:19:41 +03:00
basepath , strerror ( errno ) ) ;
return - 1 ;
}
/* Paranoia... */
2009-11-27 15:01:46 +03:00
if ( sys_fstat ( fd , & sbuf , false ) ! = 0 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " info_fn: can't fstat file %s. Error was %s \n " ) ,
2006-02-04 01:19:41 +03:00
basepath , strerror ( errno ) ) ;
close ( fd ) ;
return - 1 ;
}
2009-05-14 17:34:42 +04:00
if ( ! S_ISREG ( sbuf . st_ex_mode ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " info_fn: file %s is not a regular file. Ignoring. \n " ) ,
2006-02-04 01:19:41 +03:00
basepath ) ;
close ( fd ) ;
return - 1 ;
}
2008-10-12 19:34:43 +04:00
lines = fd_lines_load ( fd , & numlines , 10240 , NULL ) ;
2006-02-04 01:19:41 +03:00
close ( fd ) ;
if ( lines = = NULL ) {
return - 1 ;
}
/* Ensure it's well formed. */
us_err = parse_usershare_file ( ctx , & sbuf , fl - > pathname , - 1 , lines , numlines ,
2007-11-14 05:42:42 +03:00
& sharepath ,
& comment ,
2010-03-27 03:09:58 +03:00
& cp_sharename ,
2006-04-30 04:36:26 +04:00
& psd ,
& guest_ok ) ;
2006-02-04 01:19:41 +03:00
2008-10-12 19:34:43 +04:00
TALLOC_FREE ( lines ) ;
2006-03-08 11:28:42 +03:00
2006-02-04 01:19:41 +03:00
if ( us_err ! = USERSHARE_OK ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " info_fn: file %s is not a well formed usershare "
" file. \n " ) ,
2006-02-04 01:19:41 +03:00
basepath ) ;
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " info_fn: Error was %s. \n " ) ,
2006-02-04 01:19:41 +03:00
get_us_error_code ( us_err ) ) ;
return - 1 ;
}
2007-12-04 06:19:19 +03:00
acl_str = talloc_strdup ( ctx , " usershare_acl= " ) ;
if ( ! acl_str ) {
return - 1 ;
}
2006-02-04 01:19:41 +03:00
for ( num_aces = 0 ; num_aces < psd - > dacl - > num_aces ; num_aces + + ) {
const char * domain ;
const char * name ;
2006-02-15 05:07:14 +03:00
NTSTATUS ntstatus ;
2006-02-04 01:19:41 +03:00
2008-05-10 01:22:12 +04:00
ntstatus = net_lookup_name_from_sid ( c , ctx ,
& psd - > dacl - > aces [ num_aces ] . trustee ,
& domain , & name ) ;
2006-02-15 05:07:14 +03:00
2006-02-21 20:00:00 +03:00
if ( NT_STATUS_IS_OK ( ntstatus ) ) {
if ( domain & & * domain ) {
2007-12-04 06:19:19 +03:00
acl_str = talloc_asprintf_append ( acl_str ,
" %s%s " ,
domain ,
sep_str ) ;
if ( ! acl_str ) {
return - 1 ;
}
2006-02-04 01:19:41 +03:00
}
2007-12-04 06:19:19 +03:00
acl_str = talloc_asprintf_append ( acl_str ,
" %s " ,
name ) ;
if ( ! acl_str ) {
return - 1 ;
}
2006-02-04 01:19:41 +03:00
} else {
2018-12-06 20:20:06 +03:00
struct dom_sid_buf sidstr ;
acl_str = talloc_asprintf_append (
acl_str ,
" %s " ,
dom_sid_str_buf (
& psd - > dacl - > aces [ num_aces ] . trustee ,
& sidstr ) ) ;
2007-12-04 06:19:19 +03:00
if ( ! acl_str ) {
return - 1 ;
}
}
acl_str = talloc_asprintf_append ( acl_str , " : " ) ;
if ( ! acl_str ) {
return - 1 ;
2006-02-04 01:19:41 +03:00
}
2006-09-21 02:23:12 +04:00
if ( psd - > dacl - > aces [ num_aces ] . type = = SEC_ACE_TYPE_ACCESS_DENIED ) {
2007-12-04 06:19:19 +03:00
acl_str = talloc_asprintf_append ( acl_str , " D, " ) ;
if ( ! acl_str ) {
return - 1 ;
}
2006-02-04 01:19:41 +03:00
} else {
2006-09-21 02:23:12 +04:00
if ( psd - > dacl - > aces [ num_aces ] . access_mask & GENERIC_ALL_ACCESS ) {
2007-12-04 06:19:19 +03:00
acl_str = talloc_asprintf_append ( acl_str , " F, " ) ;
2006-02-04 01:19:41 +03:00
} else {
2007-12-04 06:19:19 +03:00
acl_str = talloc_asprintf_append ( acl_str , " R, " ) ;
}
if ( ! acl_str ) {
return - 1 ;
2006-02-04 01:19:41 +03:00
}
}
}
2009-08-11 10:57:01 +04:00
/* NOTE: This is smb.conf-like output. Do not translate. */
2006-02-04 01:19:41 +03:00
if ( pi - > op = = US_INFO_OP ) {
2010-03-27 03:09:58 +03:00
d_printf ( " [%s] \n " , cp_sharename ) ;
2006-02-04 01:19:41 +03:00
d_printf ( " path=%s \n " , sharepath ) ;
d_printf ( " comment=%s \n " , comment ) ;
2006-04-30 04:36:26 +04:00
d_printf ( " %s \n " , acl_str ) ;
d_printf ( " guest_ok=%c \n \n " , guest_ok ? ' y ' : ' n ' ) ;
2006-02-04 01:19:41 +03:00
} else if ( pi - > op = = US_LIST_OP ) {
2010-03-27 03:09:58 +03:00
d_printf ( " %s \n " , cp_sharename ) ;
2006-02-04 01:19:41 +03:00
}
return 0 ;
}
/***************************************************************************
Print out info ( internal detail ) on userlevel shares .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static int net_usershare_info ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
fstring wcard ;
2008-05-12 13:53:23 +04:00
bool only_ours = true ;
2006-02-04 01:19:41 +03:00
int ret = - 1 ;
2006-06-16 22:50:01 +04:00
struct us_priv_info pi ;
2006-02-04 01:19:41 +03:00
TALLOC_CTX * ctx ;
fstrcpy ( wcard , " * " ) ;
2008-05-19 18:36:18 +04:00
if ( c - > display_usage )
return net_usershare_info_usage ( c , argc , argv ) ;
2008-05-10 01:22:12 +04:00
if ( c - > opt_long_list_entries ) {
2008-05-12 13:53:23 +04:00
only_ours = false ;
2006-02-04 01:19:41 +03:00
}
switch ( argc ) {
case 0 :
break ;
case 1 :
fstrcpy ( wcard , argv [ 0 ] ) ;
break ;
default :
2008-05-10 01:22:12 +04:00
return net_usershare_info_usage ( c , argc , argv ) ;
2006-02-04 01:19:41 +03:00
}
2012-08-09 04:01:00 +04:00
if ( ! strlower_m ( wcard ) ) {
return - 1 ;
}
2006-02-04 01:19:41 +03:00
ctx = talloc_init ( " share_info " ) ;
ret = get_share_list ( ctx , wcard , only_ours ) ;
if ( ret ) {
return ret ;
}
pi . ctx = ctx ;
pi . op = US_INFO_OP ;
2008-05-10 01:22:12 +04:00
pi . c = c ;
2006-02-04 01:19:41 +03:00
ret = process_share_list ( info_fn , & pi ) ;
talloc_destroy ( ctx ) ;
return ret ;
}
2006-09-06 04:35:27 +04:00
/***************************************************************************
Count the current total number of usershares .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int count_num_usershares ( void )
{
2012-03-28 06:22:03 +04:00
DIR * dp ;
2012-03-28 06:18:14 +04:00
struct dirent * de ;
2006-09-06 04:35:27 +04:00
int num_usershares = 0 ;
2007-12-04 06:19:19 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * basepath = get_basepath ( ctx ) ;
if ( ! basepath ) {
return - 1 ;
}
2006-09-06 04:35:27 +04:00
2012-03-28 06:01:19 +04:00
dp = opendir ( basepath ) ;
2006-09-06 04:35:27 +04:00
if ( ! dp ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " count_num_usershares: cannot open usershare "
" directory %s. Error %s \n " ) ,
2006-09-06 04:35:27 +04:00
basepath , strerror ( errno ) ) ;
return - 1 ;
}
2012-03-28 06:03:00 +04:00
while ( ( de = readdir ( dp ) ) ! = 0 ) {
2006-09-06 04:35:27 +04:00
SMB_STRUCT_STAT sbuf ;
2007-12-04 06:19:19 +03:00
char * path ;
2006-09-06 04:35:27 +04:00
const char * n = de - > d_name ;
/* Ignore . and .. */
if ( * n = = ' . ' ) {
if ( ( n [ 1 ] = = ' \0 ' ) | | ( n [ 1 ] = = ' . ' & & n [ 2 ] = = ' \0 ' ) ) {
continue ;
}
}
if ( ! validate_net_name ( n , INVALID_SHARENAME_CHARS , strlen ( n ) ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " count_num_usershares: ignoring bad share "
" name %s \n " ) , n ) ;
2006-09-06 04:35:27 +04:00
continue ;
}
2007-12-04 06:19:19 +03:00
path = talloc_asprintf ( ctx ,
" %s/%s " ,
basepath ,
n ) ;
if ( ! path ) {
2012-03-28 06:08:27 +04:00
closedir ( dp ) ;
2007-12-04 06:19:19 +03:00
return - 1 ;
}
2006-09-06 04:35:27 +04:00
2009-11-27 15:02:26 +03:00
if ( sys_lstat ( path , & sbuf , false ) ! = 0 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " count_num_usershares: can't lstat file %s. "
" Error was %s \n " ) ,
2006-09-06 04:35:27 +04:00
path , strerror ( errno ) ) ;
continue ;
}
2009-05-14 17:34:42 +04:00
if ( ! S_ISREG ( sbuf . st_ex_mode ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " count_num_usershares: file %s is not a "
" regular file. Ignoring. \n " ) ,
2006-09-06 04:35:27 +04:00
path ) ;
continue ;
}
num_usershares + + ;
}
2012-03-28 06:08:27 +04:00
closedir ( dp ) ;
2006-09-06 04:35:27 +04:00
return num_usershares ;
}
2006-02-04 01:19:41 +03:00
/***************************************************************************
Add a single userlevel share .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static int net_usershare_add ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
2007-12-04 06:19:19 +03:00
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
2006-02-04 01:19:41 +03:00
SMB_STRUCT_STAT sbuf ;
SMB_STRUCT_STAT lsbuf ;
char * sharename ;
2010-03-27 03:09:58 +03:00
const char * cp_sharename ;
2007-12-04 06:19:19 +03:00
char * full_path ;
char * full_path_tmp ;
2006-02-04 01:19:41 +03:00
const char * us_path ;
const char * us_comment ;
const char * arg_acl ;
char * us_acl ;
char * file_img ;
int num_aces = 0 ;
int i ;
int tmpfd ;
const char * pacl ;
size_t to_write ;
uid_t myeuid = geteuid ( ) ;
2008-05-12 13:53:23 +04:00
bool guest_ok = false ;
2006-09-06 04:35:27 +04:00
int num_usershares ;
2013-02-25 20:34:21 +04:00
mode_t mask ;
2006-02-04 01:19:41 +03:00
us_comment = " " ;
arg_acl = " S-1-1-0:R " ;
2017-11-21 03:09:39 +03:00
if ( c - > display_usage ) {
TALLOC_FREE ( ctx ) ;
2008-05-19 18:36:18 +04:00
return net_usershare_add_usage ( c , argc , argv ) ;
2017-11-21 03:09:39 +03:00
}
2008-05-19 18:36:18 +04:00
2006-02-04 01:19:41 +03:00
switch ( argc ) {
case 0 :
case 1 :
default :
2017-11-21 03:09:39 +03:00
TALLOC_FREE ( ctx ) ;
2008-05-10 01:22:12 +04:00
return net_usershare_add_usage ( c , argc , argv ) ;
2006-02-04 01:19:41 +03:00
case 2 :
2010-03-27 03:09:58 +03:00
cp_sharename = argv [ 0 ] ;
2009-03-19 04:20:11 +03:00
sharename = strlower_talloc ( ctx , argv [ 0 ] ) ;
2006-02-04 01:19:41 +03:00
us_path = argv [ 1 ] ;
break ;
case 3 :
2010-03-27 03:09:58 +03:00
cp_sharename = argv [ 0 ] ;
2009-03-19 04:20:11 +03:00
sharename = strlower_talloc ( ctx , argv [ 0 ] ) ;
2006-02-04 01:19:41 +03:00
us_path = argv [ 1 ] ;
us_comment = argv [ 2 ] ;
break ;
case 4 :
2010-03-27 03:09:58 +03:00
cp_sharename = argv [ 0 ] ;
2009-03-19 04:20:11 +03:00
sharename = strlower_talloc ( ctx , argv [ 0 ] ) ;
2006-02-04 01:19:41 +03:00
us_path = argv [ 1 ] ;
us_comment = argv [ 2 ] ;
arg_acl = argv [ 3 ] ;
break ;
2006-04-30 04:36:26 +04:00
case 5 :
2010-03-27 03:09:58 +03:00
cp_sharename = argv [ 0 ] ;
2009-03-19 04:20:11 +03:00
sharename = strlower_talloc ( ctx , argv [ 0 ] ) ;
2006-04-30 04:36:26 +04:00
us_path = argv [ 1 ] ;
us_comment = argv [ 2 ] ;
arg_acl = argv [ 3 ] ;
2007-02-01 19:22:07 +03:00
if ( strlen ( arg_acl ) = = 0 ) {
arg_acl = " S-1-1-0:R " ;
}
2006-04-30 04:36:26 +04:00
if ( ! strnequal ( argv [ 4 ] , " guest_ok= " , 9 ) ) {
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2008-05-10 01:22:12 +04:00
return net_usershare_add_usage ( c , argc , argv ) ;
2006-04-30 04:36:26 +04:00
}
switch ( argv [ 4 ] [ 9 ] ) {
case ' y ' :
case ' Y ' :
2008-05-12 13:53:23 +04:00
guest_ok = true ;
2006-04-30 04:36:26 +04:00
break ;
case ' n ' :
case ' N ' :
2008-05-12 13:53:23 +04:00
guest_ok = false ;
2006-04-30 04:36:26 +04:00
break ;
2007-12-04 06:19:19 +03:00
default :
TALLOC_FREE ( ctx ) ;
2008-05-10 01:22:12 +04:00
return net_usershare_add_usage ( c , argc , argv ) ;
2006-04-30 04:36:26 +04:00
}
break ;
2006-02-04 01:19:41 +03:00
}
2006-09-06 04:35:27 +04:00
/* Ensure we're under the "usershare max shares" number. Advisory only. */
num_usershares = count_num_usershares ( ) ;
2007-02-01 19:22:07 +03:00
if ( num_usershares > = lp_usershare_max_shares ( ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: maximum number of allowed "
" usershares (%d) reached \n " ) ,
2007-02-01 19:22:07 +03:00
lp_usershare_max_shares ( ) ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-09-06 04:35:27 +04:00
return - 1 ;
}
2006-02-04 01:19:41 +03:00
if ( ! validate_net_name ( sharename , INVALID_SHARENAME_CHARS , strlen ( sharename ) ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " net usershare add: share name %s contains "
" invalid characters (any of %s) \n " ) ,
2006-02-04 01:19:41 +03:00
sharename , INVALID_SHARENAME_CHARS ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* Disallow shares the same as users. */
if ( getpwnam ( sharename ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: share name %s is already a valid "
" system user name \n " ) ,
2006-02-04 01:19:41 +03:00
sharename ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* Construct the full path for the usershare file. */
2007-12-04 06:19:19 +03:00
full_path = get_basepath ( ctx ) ;
if ( ! full_path ) {
TALLOC_FREE ( ctx ) ;
return - 1 ;
}
full_path_tmp = talloc_asprintf ( ctx ,
" %s/:tmpXXXXXX " ,
full_path ) ;
if ( ! full_path_tmp ) {
TALLOC_FREE ( ctx ) ;
return - 1 ;
}
full_path = talloc_asprintf_append ( full_path ,
" /%s " ,
sharename ) ;
if ( ! full_path ) {
TALLOC_FREE ( ctx ) ;
return - 1 ;
}
2006-02-04 01:19:41 +03:00
/* The path *must* be absolute. */
if ( us_path [ 0 ] ! = ' / ' ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: path %s is not an absolute "
" path. \n " ) ,
2006-02-04 01:19:41 +03:00
us_path ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* Check the directory to be shared exists. */
2009-11-27 15:03:09 +03:00
if ( sys_stat ( us_path , & sbuf , false ) ! = 0 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: cannot stat path %s to ensure "
" this is a directory. Error was %s \n " ) ,
2006-02-04 01:19:41 +03:00
us_path , strerror ( errno ) ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2009-05-14 17:34:42 +04:00
if ( ! S_ISDIR ( sbuf . st_ex_mode ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: path %s is not a directory. \n " ) ,
2006-02-04 01:19:41 +03:00
us_path ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* If we're not root, check if we're restricted to sharing out directories
that we own only . */
2009-05-14 17:34:42 +04:00
if ( ( myeuid ! = 0 ) & & lp_usershare_owner_only ( ) & & ( myeuid ! = sbuf . st_ex_uid ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " net usershare add: cannot share path %s as "
2006-02-15 05:07:14 +03:00
" we are restricted to only sharing directories we own. \n "
2008-05-12 13:53:23 +04:00
" \t Ask the administrator to add the line \" usershare owner only = false \" \n "
2009-08-11 10:57:01 +04:00
" \t to the [global] section of the smb.conf to allow this. \n " ) ,
2006-02-04 01:19:41 +03:00
us_path ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* No validation needed on comment. Now go through and validate the
acl string . Convert names to SID ' s as needed . Then run it through
parse_usershare_acl to ensure it ' s valid . */
/* Start off the string we'll append to. */
us_acl = talloc_strdup ( ctx , " " ) ;
2007-12-04 06:19:19 +03:00
if ( ! us_acl ) {
TALLOC_FREE ( ctx ) ;
return - 1 ;
}
2006-02-04 01:19:41 +03:00
pacl = arg_acl ;
num_aces = 1 ;
/* Add the number of ',' characters to get the number of aces. */
num_aces + = count_chars ( pacl , ' , ' ) ;
for ( i = 0 ; i < num_aces ; i + + ) {
2010-05-21 05:25:01 +04:00
struct dom_sid sid ;
2018-12-08 17:05:53 +03:00
struct dom_sid_buf buf ;
2006-02-04 01:19:41 +03:00
const char * pcolon = strchr_m ( pacl , ' : ' ) ;
const char * name ;
if ( pcolon = = NULL ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: malformed acl %s "
" (missing ':'). \n " ) ,
2006-02-04 01:19:41 +03:00
pacl ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
switch ( pcolon [ 1 ] ) {
case ' f ' :
case ' F ' :
case ' d ' :
case ' r ' :
case ' R ' :
break ;
default :
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: malformed acl %s "
" (access control must be 'r', 'f', "
" or 'd') \n " ) ,
2006-02-04 01:19:41 +03:00
pacl ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
if ( pcolon [ 2 ] ! = ' , ' & & pcolon [ 2 ] ! = ' \0 ' ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: malformed terminating "
" character for acl %s \n " ) ,
2006-02-04 01:19:41 +03:00
pacl ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* Get the name */
2006-06-19 23:07:39 +04:00
if ( ( name = talloc_strndup ( ctx , pacl , pcolon - pacl ) ) = = NULL ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " talloc_strndup failed \n " ) ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-06-19 23:07:39 +04:00
return - 1 ;
}
2006-02-04 01:19:41 +03:00
if ( ! string_to_sid ( & sid , name ) ) {
/* Convert to a SID */
2008-05-10 01:22:12 +04:00
NTSTATUS ntstatus = net_lookup_sid_from_name ( c , ctx , name , & sid ) ;
2006-02-15 05:07:14 +03:00
if ( ! NT_STATUS_IS_OK ( ntstatus ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: cannot convert "
" name \" %s \" to a SID. %s. " ) ,
2006-02-15 05:07:14 +03:00
name , get_friendly_nt_error_msg ( ntstatus ) ) ;
if ( NT_STATUS_EQUAL ( ntstatus , NT_STATUS_CONNECTION_REFUSED ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " Maybe smbd is not running. \n " ) ) ;
2006-02-15 05:07:14 +03:00
} else {
d_fprintf ( stderr , " \n " ) ;
}
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
}
2007-12-15 23:53:26 +03:00
us_acl = talloc_asprintf_append (
2018-12-08 17:05:53 +03:00
us_acl ,
" %s:%c, " ,
dom_sid_str_buf ( & sid , & buf ) ,
pcolon [ 1 ] ) ;
2006-02-04 01:19:41 +03:00
/* Move to the next ACL entry. */
if ( pcolon [ 2 ] = = ' , ' ) {
pacl = & pcolon [ 3 ] ;
}
}
/* Remove the last ',' */
us_acl [ strlen ( us_acl ) - 1 ] = ' \0 ' ;
2006-04-30 04:36:26 +04:00
if ( guest_ok & & ! lp_usershare_allow_guests ( ) ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr , _ ( " net usershare add: guest_ok=y requested "
" but the \" usershare allow guests \" parameter is not "
" enabled by this server. \n " ) ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-04-30 04:36:26 +04:00
return - 1 ;
}
2006-02-04 01:19:41 +03:00
/* Create a temporary filename for this share. */
2013-02-25 20:34:21 +04:00
mask = umask ( S_IRWXO | S_IRWXG ) ;
2009-04-21 01:58:26 +04:00
tmpfd = mkstemp ( full_path_tmp ) ;
2013-02-25 20:34:21 +04:00
umask ( mask ) ;
2006-02-04 01:19:41 +03:00
if ( tmpfd = = - 1 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: cannot create tmp file %s \n " ) ,
full_path_tmp ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* Ensure we opened the file we thought we did. */
2009-11-27 15:04:18 +03:00
if ( sys_lstat ( full_path_tmp , & lsbuf , false ) ! = 0 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: cannot lstat tmp file %s \n " ) ,
full_path_tmp ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2011-01-20 01:07:33 +03:00
close ( tmpfd ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* Check this is the same as the file we opened. */
2009-11-27 15:04:38 +03:00
if ( sys_fstat ( tmpfd , & sbuf , false ) ! = 0 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: cannot fstat tmp file %s \n " ) ,
full_path_tmp ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2011-01-20 01:07:33 +03:00
close ( tmpfd ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2009-05-14 17:34:42 +04:00
if ( ! S_ISREG ( sbuf . st_ex_mode ) | | sbuf . st_ex_dev ! = lsbuf . st_ex_dev | | sbuf . st_ex_ino ! = lsbuf . st_ex_ino ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: tmp file %s is not a regular "
" file ? \n " ) ,
full_path_tmp ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2011-01-20 01:07:33 +03:00
close ( tmpfd ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2007-12-04 06:19:19 +03:00
2006-02-04 01:19:41 +03:00
if ( fchmod ( tmpfd , 0644 ) = = - 1 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: failed to fchmod tmp file %s "
" to 0644n " ) ,
full_path_tmp ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2011-01-20 01:07:33 +03:00
close ( tmpfd ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* Create the in-memory image of the file. */
2006-04-30 04:36:26 +04:00
file_img = talloc_strdup ( ctx , " #VERSION 2 \n path= " ) ;
2010-03-27 03:09:58 +03:00
file_img = talloc_asprintf_append ( file_img ,
" %s \n comment=%s \n usershare_acl=%s \n "
" guest_ok=%c \n sharename=%s \n " ,
us_path ,
us_comment ,
us_acl ,
guest_ok ? ' y ' : ' n ' ,
cp_sharename ) ;
2006-02-04 01:19:41 +03:00
to_write = strlen ( file_img ) ;
if ( write ( tmpfd , file_img , to_write ) ! = to_write ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: failed to write %u bytes to "
" file %s. Error was %s \n " ) ,
2006-02-04 01:19:41 +03:00
( unsigned int ) to_write , full_path_tmp , strerror ( errno ) ) ;
unlink ( full_path_tmp ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2011-01-20 01:07:33 +03:00
close ( tmpfd ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
/* Attempt to replace any existing share by this name. */
if ( rename ( full_path_tmp , full_path ) ! = 0 ) {
unlink ( full_path_tmp ) ;
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare add: failed to add share %s. Error "
" was %s \n " ) ,
2006-02-04 01:19:41 +03:00
sharename , strerror ( errno ) ) ;
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
close ( tmpfd ) ;
return - 1 ;
}
close ( tmpfd ) ;
2008-05-10 01:22:12 +04:00
if ( c - > opt_long_list_entries ) {
2006-02-04 01:19:41 +03:00
const char * my_argv [ 2 ] ;
my_argv [ 0 ] = sharename ;
my_argv [ 1 ] = NULL ;
2008-05-10 01:22:12 +04:00
net_usershare_info ( c , 1 , my_argv ) ;
2006-02-04 01:19:41 +03:00
}
2007-12-04 06:19:19 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return 0 ;
}
#if 0
/***************************************************************************
List function .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-06 21:03:57 +03:00
static int list_fn ( struct file_list * fl , void * priv )
2006-02-04 01:19:41 +03:00
{
d_printf ( " %s \n " , fl - > pathname ) ;
return 0 ;
}
# endif
/***************************************************************************
List userlevel shares .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static int net_usershare_list ( struct net_context * c , int argc ,
const char * * argv )
2006-02-04 01:19:41 +03:00
{
fstring wcard ;
2008-05-12 13:53:23 +04:00
bool only_ours = true ;
2006-02-04 01:19:41 +03:00
int ret = - 1 ;
2006-06-16 22:50:01 +04:00
struct us_priv_info pi ;
2006-02-04 01:19:41 +03:00
TALLOC_CTX * ctx ;
fstrcpy ( wcard , " * " ) ;
2008-05-19 18:36:18 +04:00
if ( c - > display_usage )
return net_usershare_list_usage ( c , argc , argv ) ;
2008-05-10 01:22:12 +04:00
if ( c - > opt_long_list_entries ) {
2008-05-12 13:53:23 +04:00
only_ours = false ;
2006-02-04 01:19:41 +03:00
}
switch ( argc ) {
case 0 :
break ;
case 1 :
fstrcpy ( wcard , argv [ 0 ] ) ;
break ;
default :
2008-05-10 01:22:12 +04:00
return net_usershare_list_usage ( c , argc , argv ) ;
2006-02-04 01:19:41 +03:00
}
2012-08-09 04:01:00 +04:00
if ( ! strlower_m ( wcard ) ) {
return - 1 ;
}
2006-02-04 01:19:41 +03:00
ctx = talloc_init ( " share_list " ) ;
ret = get_share_list ( ctx , wcard , only_ours ) ;
if ( ret ) {
return ret ;
}
pi . ctx = ctx ;
pi . op = US_LIST_OP ;
2009-07-18 04:01:56 +04:00
pi . c = c ;
2006-02-04 01:19:41 +03:00
ret = process_share_list ( info_fn , & pi ) ;
talloc_destroy ( ctx ) ;
return ret ;
}
/***************************************************************************
Entry - point for all the USERSHARE functions .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
int net_usershare ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
2019-11-05 14:14:37 +03:00
const struct loadparm_substitution * lp_sub =
loadparm_s3_global_substitution ( ) ;
2012-03-28 06:22:03 +04:00
DIR * dp ;
2006-02-04 01:19:41 +03:00
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-19 18:36:18 +04:00
{
" add " ,
net_usershare_add ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:57:01 +04:00
N_ ( " Add/modify user defined share " ) ,
N_ ( " net usershare add \n "
" Add/modify user defined share " )
2008-05-19 18:36:18 +04:00
} ,
{
" delete " ,
net_usershare_delete ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:57:01 +04:00
N_ ( " Delete user defined share " ) ,
N_ ( " net usershare delete \n "
" Delete user defined share " )
2008-05-19 18:36:18 +04:00
} ,
{
" info " ,
net_usershare_info ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:57:01 +04:00
N_ ( " Display information about a user defined share " ) ,
N_ ( " net usershare info \n "
" Display information about a user defined share " )
2008-05-19 18:36:18 +04:00
} ,
{
" list " ,
net_usershare_list ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:57:01 +04:00
N_ ( " List user defined shares " ) ,
N_ ( " net usershare list \n "
" List user defined shares " )
2008-05-19 18:36:18 +04:00
} ,
{ NULL , NULL , 0 , NULL , NULL }
2006-02-04 01:19:41 +03:00
} ;
2008-05-08 13:23:38 +04:00
2006-02-04 01:19:41 +03:00
if ( lp_usershare_max_shares ( ) = = 0 ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare: usershares are currently "
" disabled \n " ) ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2019-11-05 14:14:37 +03:00
dp = opendir ( lp_usershare_path ( talloc_tos ( ) , lp_sub ) ) ;
2006-02-04 01:19:41 +03:00
if ( ! dp ) {
int err = errno ;
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " net usershare: cannot open usershare directory %s. "
" Error %s \n " ) ,
2019-11-05 14:14:37 +03:00
lp_usershare_path ( talloc_tos ( ) , lp_sub ) , strerror ( err ) ) ;
2006-02-04 01:19:41 +03:00
if ( err = = EACCES ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " You do not have permission to create a "
" usershare. Ask your administrator to grant "
" you permissions to create a share. \n " ) ) ;
2006-02-04 01:19:41 +03:00
} else if ( err = = ENOENT ) {
2009-08-11 10:57:01 +04:00
d_fprintf ( stderr ,
_ ( " Please ask your system administrator to "
" enable user sharing. \n " ) ) ;
2006-02-04 01:19:41 +03:00
}
return - 1 ;
}
2012-03-28 06:08:27 +04:00
closedir ( dp ) ;
2006-02-04 01:19:41 +03:00
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net usershare " , func ) ;
2006-02-04 01:19:41 +03:00
}