summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h6
-rw-r--r--source3/include/rpc_srvsvc.h21
-rw-r--r--source3/rpc_parse/parse_srv.c75
-rw-r--r--source3/rpc_server/srv_srvsvc.c62
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c167
5 files changed, 331 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 95cdfeda7f..f1be2de1ae 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/include/rpc_srvsvc.h b/source3/include/rpc_srvsvc.h
index f814d3a70d..d6fe7617b2 100644
--- a/source3/include/rpc_srvsvc.h
+++ b/source3/include/rpc_srvsvc.h
@@ -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 */
diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c
index ae6f99c56e..9661b4edf1 100644
--- a/source3/rpc_parse/parse_srv.c
+++ b/source3/rpc_parse/parse_srv.c
@@ -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;
+}
diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c
index 76542d1c2f..3fa782001c 100644
--- a/source3/rpc_server/srv_srvsvc.c
+++ b/source3/rpc_server/srv_srvsvc.c
@@ -405,6 +405,66 @@ static BOOL api_srv_net_name_validate(pipes_struct *p)
}
/*******************************************************************
+ 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 }
};
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 13d27788e0..7ae95a5eac 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -1564,6 +1564,173 @@ uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET
}
/***********************************************************************************
+ 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.
These disks would the disks listed by this function.