summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/param/loadparm.c9
-rw-r--r--source3/rpc_server/srv_pipe.c16
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c16
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c95
5 files changed, 111 insertions, 29 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index abb1d58b6e..dc2e17f341 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1646,6 +1646,9 @@ char *lp_ldap_suffix(void);
char *lp_ldap_filter(void);
char *lp_ldap_root(void);
char *lp_ldap_rootpasswd(void);
+char *lp_add_share_cmd(void);
+char *lp_change_share_cmd(void);
+char *lp_delete_share_cmd(void);
int lp_ssl_version(void);
char *lp_ssl_hosts(void);
char *lp_ssl_hosts_resign(void);
@@ -3625,6 +3628,7 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
RPC_IFACE* transfer);
BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p);
BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in);
+struct current_user *get_current_user(struct current_user *user, pipes_struct *p);
BOOL api_pipe_request(pipes_struct *p);
BOOL api_rpcTNP(pipes_struct *p, char *rpc_name,
struct api_struct *api_rpc_cmds);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index bec5f03cd8..59e66d8ce1 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -181,6 +181,9 @@ typedef struct
char *szTemplateHomedir;
char *szTemplateShell;
char *szWinbindSeparator;
+ char *szAddShareCommand;
+ char *szChangeShareCommand;
+ char *szDeleteShareCommand;
int max_log_size;
int mangled_stack;
int max_xmit;
@@ -960,6 +963,9 @@ static struct parm_struct parm_table[] = {
#endif /* WITH_LDAP */
{"Miscellaneous Options", P_SEP, P_SEPARATOR},
+ {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, 0},
+ {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, 0},
+ {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, 0},
{"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
@@ -1501,6 +1507,9 @@ FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter);
FN_GLOBAL_STRING(lp_ldap_root, &Globals.szLdapRoot);
FN_GLOBAL_STRING(lp_ldap_rootpasswd, &Globals.szLdapRootPassword);
#endif /* WITH_LDAP */
+FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand);
+FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand);
+FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand);
#ifdef WITH_SSL
FN_GLOBAL_INTEGER(lp_ssl_version, &Globals.sslVersion);
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index bc5b2ab473..32ec81b07a 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -1104,6 +1104,22 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
}
/****************************************************************************
+ Return a user struct for a pipe user.
+****************************************************************************/
+
+struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
+{
+ if (p->ntlmssp_auth_validated) {
+ memcpy(user, &p->pipe_user, sizeof(struct current_user));
+ } else {
+ extern struct current_user current_user;
+ memcpy(user, &current_user, sizeof(struct current_user));
+ }
+
+ return user;
+}
+
+/****************************************************************************
Find the correct RPC function to call for this request.
If the pipe is authenticated then become the correct UNIX user
before doing the call.
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 90147c868a..c75af92902 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -223,22 +223,6 @@ SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
}
/****************************************************************************
- Return a user struct for a pipe user.
-****************************************************************************/
-
-static struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
-{
- if (p->ntlmssp_auth_validated) {
- memcpy(user, &p->pipe_user, sizeof(struct current_user));
- } else {
- extern struct current_user current_user;
- memcpy(user, &current_user, sizeof(struct current_user));
- }
-
- return user;
-}
-
-/****************************************************************************
find printer index by handle
****************************************************************************/
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 0e03918bfb..fb911a0d85 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -928,12 +928,12 @@ uint32 _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET
uint32 _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
{
- char *share_name;
+ fstring share_name;
DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
/* Create the list of shares for the response. */
- share_name = dos_unistr2_to_str(&q_u->uni_share_name);
+ unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
init_srv_r_net_share_get_info(p->mem_ctx, r_u, share_name, q_u->info_level);
DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
@@ -947,13 +947,16 @@ uint32 _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S
uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
{
- char *share_name;
+ fstring share_name;
uint32 status = NT_STATUS_NOPROBLEMO;
int snum;
+ fstring servicename;
+ fstring comment;
+ pstring pathname;
DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
- share_name = dos_unistr2_to_str(&q_u->uni_share_name);
+ unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
r_u->switch_value = 0;
@@ -993,29 +996,51 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
}
/*******************************************************************
- Net share add. Stub for now. JRA.
+ Net share add. Call 'add_share_command "sharename" "pathname" "comment"'
********************************************************************/
uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
{
+ struct current_user user;
+ pstring command;
uint32 status = NT_STATUS_NOPROBLEMO;
+ fstring share_name;
+ fstring comment;
+ pstring pathname;
+ char *ptr;
+ int type;
+ int snum;
DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
r_u->switch_value = 0;
+ get_current_user(&user,p);
+
+ if (user.uid != 0)
+ return ERROR_ACCESS_DENIED;
+
+ if (!lp_add_share_cmd())
+ return ERROR_ACCESS_DENIED;
+
switch (q_u->info_level) {
case 1:
+ /* Not enough info in a level 1 to do anything. */
status = ERROR_ACCESS_DENIED;
break;
case 2:
- status = ERROR_ACCESS_DENIED;
+ unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
+ unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
+ unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
break;
case 502:
/* we set sd's here. FIXME. JRA */
- status = ERROR_ACCESS_DENIED;
+ unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
+ unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
+ unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
break;
case 1005:
+ /* DFS only level. */
status = ERROR_ACCESS_DENIED;
break;
default:
@@ -1024,6 +1049,26 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
break;
}
+ snum = find_service(share_name);
+
+ /* Share already exists. */
+ if (snum >= 0)
+ return NT_STATUS_BAD_NETWORK_NAME;
+
+ /* Convert any '\' paths to '/' */
+ unix_format(pathname);
+ unix_clean_name(pathname);
+
+ /* NT is braindead - it wants a C: prefix to a pathname ! */
+ ptr = pathname;
+ if (strlen(pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
+ ptr += 2;
+
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\"",
+ lp_add_share_cmd(), share_name, ptr, comment );
+
+/* HERE ! JRA */
+
r_u->status = status;
DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
@@ -1032,26 +1077,50 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
}
/*******************************************************************
- Net share delete. Stub for now. JRA.
+ Net share delete. Call "delete share command" with the share name as
+ a parameter.
********************************************************************/
uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
{
- char *share_name;
- uint32 status = NT_STATUS_NOPROBLEMO;
+ struct current_user user;
+ pstring command;
+ fstring share_name;
+ int ret;
int snum;
DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
- share_name = dos_unistr2_to_str(&q_u->uni_share_name);
+ unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
snum = find_service(share_name);
if (snum < 0)
return NT_STATUS_BAD_NETWORK_NAME;
- /* Stub... */
- return ERROR_ACCESS_DENIED;
+ get_current_user(&user,p);
+
+ if (user.uid != 0)
+ return ERROR_ACCESS_DENIED;
+
+ if (!lp_delete_share_cmd())
+ return ERROR_ACCESS_DENIED;
+
+ slprintf(command, sizeof(command)-1, "%s \"%s\"", lp_delete_share_cmd(), lp_servicename(snum));
+ dos_to_unix(command, True); /* Convert to unix-codepage */
+
+ DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
+ if ((ret = smbrun(command, NULL, False)) != 0) {
+ DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
+ return ERROR_ACCESS_DENIED;
+ }
+
+ /* Send SIGHUP to process group. */
+ kill(0, SIGHUP);
+
+ lp_killservice(snum);
+
+ return NT_STATUS_NOPROBLEMO;
}
/*******************************************************************