1
0
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:
Jeremy Allison 0001-01-01 00:00:00 +00:00
parent bc366f3153
commit 5690ec77c8
5 changed files with 331 additions and 0 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 }
};

View File

@ -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.