diff options
-rw-r--r-- | source3/include/proto.h | 4 | ||||
-rw-r--r-- | source3/param/loadparm.c | 9 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 16 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 16 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 95 |
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, ¤t_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, ¤t_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; } /******************************************************************* |