mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
Modified version of Jim's 0x27 and 0x28 Win9x Secdesc patch.
Jeremy.
This commit is contained in:
parent
bc366f3153
commit
5690ec77c8
@ -3713,6 +3713,8 @@ BOOL srv_io_q_net_name_validate(char *desc, SRV_Q_NET_NAME_VALIDATE *q_n, prs_st
|
||||
BOOL srv_io_r_net_name_validate(char *desc, SRV_R_NET_NAME_VALIDATE *r_n, prs_struct *ps, int depth);
|
||||
BOOL srv_io_q_net_file_query_secdesc(char *desc, SRV_Q_NET_FILE_QUERY_SECDESC *q_n, prs_struct *ps, int depth);
|
||||
BOOL srv_io_r_net_file_query_secdesc(char *desc, SRV_R_NET_FILE_QUERY_SECDESC *r_n, prs_struct *ps, int depth);
|
||||
BOOL srv_io_q_net_file_set_secdesc(char *desc, SRV_Q_NET_FILE_SET_SECDESC *q_n, prs_struct *ps, int depth);
|
||||
BOOL srv_io_r_net_file_set_secdesc(char *desc, SRV_R_NET_FILE_SET_SECDESC *r_n, prs_struct *ps, int depth);
|
||||
|
||||
/* The following definitions come from rpc_parse/parse_wks.c */
|
||||
|
||||
@ -3940,6 +3942,10 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
|
||||
uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u);
|
||||
uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u);
|
||||
uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u);
|
||||
uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
|
||||
SRV_R_NET_FILE_QUERY_SECDESC *r_u);
|
||||
uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
|
||||
SRV_R_NET_FILE_SET_SECDESC *r_u);
|
||||
uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u);
|
||||
uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u);
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#define SRV_NET_NAME_VALIDATE 0x21
|
||||
#define SRV_NETSHAREENUM 0x24
|
||||
#define SRV_NETFILEQUERYSECDESC 0x27
|
||||
#define SRV_NETFILESETSECDESC 0x28
|
||||
|
||||
#define MAX_SERVER_DISK_ENTRIES 15
|
||||
|
||||
@ -788,4 +789,24 @@ typedef struct r_net_file_query_secdesc
|
||||
uint32 status;
|
||||
} SRV_R_NET_FILE_QUERY_SECDESC;
|
||||
|
||||
/* SRV_Q_NET_FILE_SET_SECDESC */
|
||||
typedef struct q_net_file_set_secdesc
|
||||
{
|
||||
uint32 ptr_srv_name;
|
||||
UNISTR2 uni_srv_name;
|
||||
uint32 ptr_qual_name;
|
||||
UNISTR2 uni_qual_name;
|
||||
UNISTR2 uni_file_name;
|
||||
uint32 sec_info;
|
||||
uint32 size_set;
|
||||
uint32 ptr_secdesc;
|
||||
uint32 size_secdesc;
|
||||
SEC_DESC *sec_desc;
|
||||
} SRV_Q_NET_FILE_SET_SECDESC;
|
||||
|
||||
/* SRV_R_NET_FILE_SET_SECDESC */
|
||||
typedef struct r_net_file_set_secdesc
|
||||
{
|
||||
uint32 status;
|
||||
} SRV_R_NET_FILE_SET_SECDESC;
|
||||
#endif /* _RPC_SRVSVC_H */
|
||||
|
@ -2647,3 +2647,78 @@ BOOL srv_io_r_net_file_query_secdesc(char *desc, SRV_R_NET_FILE_QUERY_SECDESC *r
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes a structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL srv_io_q_net_file_set_secdesc(char *desc, SRV_Q_NET_FILE_SET_SECDESC *q_n, prs_struct *ps, int depth)
|
||||
{
|
||||
if (q_n == NULL)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "srv_io_q_net_file_set_secdesc");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
|
||||
return False;
|
||||
|
||||
if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name))
|
||||
return False;
|
||||
|
||||
if(!smb_io_unistr2("", &q_n->uni_qual_name, True, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!smb_io_unistr2("", &q_n->uni_file_name, True, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("sec_info", ps, depth, &q_n->sec_info))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("size_set", ps, depth, &q_n->size_set))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("ptr_secdesc", ps, depth, &q_n->ptr_secdesc))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("size_secdesc", ps, depth, &q_n->size_secdesc))
|
||||
return False;
|
||||
|
||||
if(!sec_io_desc("sec_desc", &q_n->sec_desc, ps, depth))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Reads or writes a structure.
|
||||
********************************************************************/
|
||||
|
||||
BOOL srv_io_r_net_file_set_secdesc(char *desc, SRV_R_NET_FILE_SET_SECDESC *r_n, prs_struct *ps, int depth)
|
||||
{
|
||||
if (r_n == NULL)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "srv_io_r_net_file_set_secdesc");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("status", ps, depth, &r_n->status))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
@ -404,6 +404,66 @@ static BOOL api_srv_net_name_validate(pipes_struct *p)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
NetFileQuerySecdesc (opnum 0x27)
|
||||
*******************************************************************/
|
||||
|
||||
static BOOL api_srv_net_file_query_secdesc(pipes_struct *p)
|
||||
{
|
||||
SRV_Q_NET_FILE_QUERY_SECDESC q_u;
|
||||
SRV_R_NET_FILE_QUERY_SECDESC r_u;
|
||||
prs_struct *data = &p->in_data.data;
|
||||
prs_struct *rdata = &p->out_data.rdata;
|
||||
|
||||
ZERO_STRUCT(q_u);
|
||||
ZERO_STRUCT(r_u);
|
||||
|
||||
/* Unmarshall the net file get info from Win9x */
|
||||
if(!srv_io_q_net_file_query_secdesc("", &q_u, data, 0)) {
|
||||
DEBUG(0,("api_srv_net_file_query_secdesc: Failed to unmarshall SRV_Q_NET_FILE_QUERY_SECDESC.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
r_u.status = _srv_net_file_query_secdesc(p, &q_u, &r_u);
|
||||
|
||||
if(!srv_io_r_net_file_query_secdesc("", &r_u, rdata, 0)) {
|
||||
DEBUG(0,("api_srv_net_file_query_secdesc: Failed to marshall SRV_R_NET_FILE_QUERY_SECDESC.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
NetFileSetSecdesc (opnum 0x28)
|
||||
*******************************************************************/
|
||||
|
||||
static BOOL api_srv_net_file_set_secdesc(pipes_struct *p)
|
||||
{
|
||||
SRV_Q_NET_FILE_SET_SECDESC q_u;
|
||||
SRV_R_NET_FILE_SET_SECDESC r_u;
|
||||
prs_struct *data = &p->in_data.data;
|
||||
prs_struct *rdata = &p->out_data.rdata;
|
||||
|
||||
ZERO_STRUCT(q_u);
|
||||
ZERO_STRUCT(r_u);
|
||||
|
||||
/* Unmarshall the net file set info from Win9x */
|
||||
if(!srv_io_q_net_file_set_secdesc("", &q_u, data, 0)) {
|
||||
DEBUG(0,("api_srv_net_file_set_secdesc: Failed to unmarshall SRV_Q_NET_FILE_SET_SECDESC.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
r_u.status = _srv_net_file_set_secdesc(p, &q_u, &r_u);
|
||||
|
||||
if(!srv_io_r_net_file_set_secdesc("", &r_u, rdata, 0)) {
|
||||
DEBUG(0,("api_srv_net_file_set_secdesc: Failed to marshall SRV_R_NET_FILE_SET_SECDESC.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
\PIPE\srvsvc commands
|
||||
********************************************************************/
|
||||
@ -423,6 +483,8 @@ struct api_struct api_srv_cmds[] =
|
||||
{ "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
|
||||
{ "SRV_NET_DISK_ENUM" , SRV_NET_DISK_ENUM , api_srv_net_disk_enum },
|
||||
{ "SRV_NET_NAME_VALIDATE" , SRV_NET_NAME_VALIDATE , api_srv_net_name_validate},
|
||||
{ "SRV_NETFILEQUERYSECDESC",SRV_NETFILEQUERYSECDESC,api_srv_net_file_query_secdesc},
|
||||
{ "SRV_NETFILESETSECDESC" , SRV_NETFILESETSECDESC , api_srv_net_file_set_secdesc},
|
||||
{ NULL , 0 , NULL }
|
||||
};
|
||||
|
||||
|
@ -1563,6 +1563,173 @@ uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET
|
||||
return r_u->status;
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
Win9x NT tools get security descriptor.
|
||||
***********************************************************************************/
|
||||
|
||||
uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
|
||||
SRV_R_NET_FILE_QUERY_SECDESC *r_u)
|
||||
{
|
||||
SEC_DESC *psd = NULL;
|
||||
size_t sd_size;
|
||||
fstring null_pw;
|
||||
pstring filename;
|
||||
pstring qualname;
|
||||
files_struct *fsp = NULL;
|
||||
SMB_STRUCT_STAT st;
|
||||
BOOL bad_path;
|
||||
int access_mode;
|
||||
int action;
|
||||
int ecode;
|
||||
struct current_user user;
|
||||
fstring user_name;
|
||||
connection_struct *conn = NULL;
|
||||
|
||||
ZERO_STRUCT(st);
|
||||
|
||||
r_u->status = NT_STATUS_NOPROBLEMO;
|
||||
|
||||
unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
|
||||
|
||||
/* Null password is ok - we are already an authenticated user... */
|
||||
*null_pw = '\0';
|
||||
|
||||
get_current_user(&user, p);
|
||||
fstrcpy(user_name, uidtoname(user.uid));
|
||||
|
||||
conn = make_connection(qualname, user_name, "", 0, "A:", user.vuid, &ecode);
|
||||
|
||||
if (conn == NULL) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
|
||||
r_u->status = (uint32)ecode;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
|
||||
unix_convert(filename, conn, NULL, &bad_path, &st);
|
||||
fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
|
||||
|
||||
if (!fsp) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
|
||||
r_u->status = ERROR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
|
||||
|
||||
if (sd_size == 0) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
|
||||
r_u->status = ERROR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
r_u->ptr_response = 1;
|
||||
r_u->size_response = sd_size;
|
||||
r_u->ptr_secdesc = 1;
|
||||
r_u->size_secdesc = sd_size;
|
||||
r_u->sec_desc = psd;
|
||||
|
||||
psd->dacl->revision = (uint16) NT4_ACL_REVISION;
|
||||
|
||||
fsp->conn->vfs_ops.close(fsp, fsp->fd);
|
||||
file_free(fsp);
|
||||
|
||||
close_cnum(conn, user.vuid);
|
||||
return r_u->status;
|
||||
|
||||
error_exit:
|
||||
|
||||
if(fsp) {
|
||||
fsp->conn->vfs_ops.close(fsp, fsp->fd);
|
||||
file_free(fsp);
|
||||
}
|
||||
|
||||
if (conn)
|
||||
close_cnum(conn, user.vuid);
|
||||
|
||||
return r_u->status;
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
Win9x NT tools set security descriptor.
|
||||
***********************************************************************************/
|
||||
|
||||
uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
|
||||
SRV_R_NET_FILE_SET_SECDESC *r_u)
|
||||
{
|
||||
BOOL ret;
|
||||
pstring filename;
|
||||
pstring qualname;
|
||||
fstring null_pw;
|
||||
files_struct *fsp = NULL;
|
||||
SMB_STRUCT_STAT st;
|
||||
BOOL bad_path;
|
||||
int access_mode;
|
||||
int action;
|
||||
int ecode;
|
||||
struct current_user user;
|
||||
fstring user_name;
|
||||
connection_struct *conn = NULL;
|
||||
|
||||
ZERO_STRUCT(st);
|
||||
|
||||
r_u->status = NT_STATUS_NOPROBLEMO;
|
||||
|
||||
unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
|
||||
|
||||
/* Null password is ok - we are already an authenticated user... */
|
||||
*null_pw = '\0';
|
||||
|
||||
get_current_user(&user, p);
|
||||
fstrcpy(user_name, uidtoname(user.uid));
|
||||
|
||||
conn = make_connection(qualname, user_name, null_pw, 0, "A:", user.vuid, &ecode);
|
||||
|
||||
if (conn == NULL) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
|
||||
r_u->status = (uint32)ecode;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
|
||||
unix_convert(filename, conn, NULL, &bad_path, &st);
|
||||
|
||||
fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
|
||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
|
||||
|
||||
if (!fsp) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
|
||||
r_u->status = ERROR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
|
||||
|
||||
if (ret == False) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
|
||||
r_u->status = ERROR_ACCESS_DENIED;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
fsp->conn->vfs_ops.close(fsp, fsp->fd);
|
||||
file_free(fsp);
|
||||
close_cnum(conn, user.vuid);
|
||||
return r_u->status;
|
||||
|
||||
error_exit:
|
||||
|
||||
if(fsp) {
|
||||
fsp->conn->vfs_ops.close(fsp, fsp->fd);
|
||||
file_free(fsp);
|
||||
}
|
||||
|
||||
if (conn)
|
||||
close_cnum(conn, user.vuid);
|
||||
|
||||
return r_u->status;
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
|
||||
We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
|
||||
|
Loading…
Reference in New Issue
Block a user