1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-15 23:24:37 +03:00

481 lines
12 KiB
C
Raw Normal View History

/*
Unix SMB/CIFS implementation.
NT Domain Authentication SMB / MSRPC client
Copyright (C) Andrew Tridgell 1994-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Tim Potter 2001
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
WERROR cli_srvsvc_net_srv_get_info(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
uint32 switch_value, SRV_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_SRV_GET_INFO q;
SRV_R_NET_SRV_GET_INFO r;
WERROR result = W_ERROR(ERRgeneral);
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Initialise input parameters */
init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value);
/* Marshall data and send request */
if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
r.ctr = ctr;
if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0))
goto done;
result = r.status;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 info_level, SRV_SHARE_INFO_CTR *ctr,
int preferred_len, ENUM_HND *hnd)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_SHARE_ENUM q;
SRV_R_NET_SHARE_ENUM r;
WERROR result = W_ERROR(ERRgeneral);
int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Initialise input parameters */
init_srv_q_net_share_enum(
&q, cli->srv_name_slash, info_level, preferred_len, hnd);
/* Marshall data and send request */
if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
if (!srv_io_r_net_share_enum("", &r, &rbuf, 0))
goto done;
result = r.status;
if (!W_ERROR_IS_OK(result))
goto done;
/* Oh yuck yuck yuck - we have to copy all the info out of the
SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a
prs_mem_free() it will all be invalidated. The various share
info structures suck badly too. This really is gross. */
ZERO_STRUCTP(ctr);
if (!r.ctr.num_entries)
goto done;
ctr->info_level = info_level;
ctr->num_entries = r.ctr.num_entries;
switch(info_level) {
case 1:
ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc(
mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries);
memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
for (i = 0; i < ctr->num_entries; i++) {
SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i];
char *s;
/* Copy pointer crap */
memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1,
sizeof(SH_INFO_1));
/* Duplicate strings */
s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname);
if (s)
init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark);
if (s)
init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
}
break;
case 2:
ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc(
mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries);
memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
for (i = 0; i < ctr->num_entries; i++) {
SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i];
char *s;
/* Copy pointer crap */
memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2,
sizeof(SH_INFO_2));
/* Duplicate strings */
s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname);
if (s)
init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark);
if (s)
init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path);
if (s)
init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd);
if (s)
init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
}
break;
/* adding info-level 502 here */
case 502:
ctr->share.info502 = (SRV_SHARE_INFO_502 *)talloc(
mem_ctx, sizeof(SRV_SHARE_INFO_502) * ctr->num_entries);
memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
for (i = 0; i < ctr->num_entries; i++) {
SRV_SHARE_INFO_502 *info502 = &ctr->share.info502[i];
char *s;
/* Copy pointer crap */
memcpy(&info502->info_502, &r.ctr.share.info502[i].info_502,
sizeof(SH_INFO_502));
/* Duplicate strings */
s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_netname);
if (s)
init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_remark);
if (s)
init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_path);
if (s)
init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_passwd);
if (s)
init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
info502->info_502_str.sd = dup_sec_desc(mem_ctx, r.ctr.share.info502[i].info_502_str.sd);
}
break;
}
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx,
const char *sharename)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_SHARE_DEL q;
SRV_R_NET_SHARE_DEL r;
WERROR result = W_ERROR(ERRgeneral);
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Initialise input parameters */
init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename);
/* Marshall data and send request */
if (!srv_io_q_net_share_del("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
if (!srv_io_r_net_share_del("", &r, &rbuf, 0))
goto done;
result = r.status;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
const char *netname, uint32 type,
const char *remark, uint32 perms,
uint32 max_uses, uint32 num_uses,
r1692: first commit :) * add IA64 to the architecture table of printer-drivers * add new "net"-subcommands: net rpc printer migrate {drivers|printers|forms|security|settings|all} [printer] net rpc share migrate {shares|files|all} [share] this is the first part of the migration suite. this will will (once feature-complete) allow to do 1:1 server-cloning in the best possible way by making heavy use of samba's rpc_client-functions. all migration-steps are implemented as rpc/smb-client-calls; net communicates via rpc/smb with two servers at the same time (a remote, source server and a destination server that currently defaults to the local smbd). this allows e. g. printer-driver migration including driverfiles, recursive mirroring of file-shares including file-acls, etc. almost any migration step can be called with a migrate-subcommand to provide more flexibility during a migration process (at the cost of quite some redundancy :) ). "net rpc printer migrate settings" is still in a bad condition (many open questions that hopefully can be adressed soon). "net rpc share migrate security" as an isolated call to just migrate share-ACLs will be added later. Before playing with it, make sure to use a test-server. Migration is a serious business and this tool-set can perfectly overwrite your existing file/print-shares. * along with the migration functions had to make I the following changes: - implement setprinter level 3 client-side - implement net_add_share level 502 client-side - allow security descriptor to be set in setprinterdata level 2 serverside guenther (This used to be commit 8f1716a29b7e85baf738bc14df7dabf03762f723)
2004-08-10 14:27:17 +00:00
const char *path, const char *passwd,
int level, SEC_DESC *sd)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_SHARE_ADD q;
SRV_R_NET_SHARE_ADD r;
WERROR result = W_ERROR(ERRgeneral);
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark,
r1692: first commit :) * add IA64 to the architecture table of printer-drivers * add new "net"-subcommands: net rpc printer migrate {drivers|printers|forms|security|settings|all} [printer] net rpc share migrate {shares|files|all} [share] this is the first part of the migration suite. this will will (once feature-complete) allow to do 1:1 server-cloning in the best possible way by making heavy use of samba's rpc_client-functions. all migration-steps are implemented as rpc/smb-client-calls; net communicates via rpc/smb with two servers at the same time (a remote, source server and a destination server that currently defaults to the local smbd). this allows e. g. printer-driver migration including driverfiles, recursive mirroring of file-shares including file-acls, etc. almost any migration step can be called with a migrate-subcommand to provide more flexibility during a migration process (at the cost of quite some redundancy :) ). "net rpc printer migrate settings" is still in a bad condition (many open questions that hopefully can be adressed soon). "net rpc share migrate security" as an isolated call to just migrate share-ACLs will be added later. Before playing with it, make sure to use a test-server. Migration is a serious business and this tool-set can perfectly overwrite your existing file/print-shares. * along with the migration functions had to make I the following changes: - implement setprinter level 3 client-side - implement net_add_share level 502 client-side - allow security descriptor to be set in setprinterdata level 2 serverside guenther (This used to be commit 8f1716a29b7e85baf738bc14df7dabf03762f723)
2004-08-10 14:27:17 +00:00
perms, max_uses, num_uses, path, passwd,
level, sd);
/* Marshall data and send request */
if (!srv_io_q_net_share_add("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
if (!srv_io_r_net_share_add("", &r, &rbuf, 0))
goto done;
result = r.status;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx,
char *server, TIME_OF_DAY_INFO *tod)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_REMOTE_TOD q;
SRV_R_NET_REMOTE_TOD r;
WERROR result = W_ERROR(ERRgeneral);
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Initialise input parameters */
init_srv_q_net_remote_tod(&q, cli->srv_name_slash);
/* Marshall data and send request */
if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
r.tod = tod;
if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0))
goto done;
result = r.status;
if (!W_ERROR_IS_OK(result))
goto done;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 file_level, const char *user_name,
SRV_FILE_INFO_CTR *ctr, int preferred_len,
ENUM_HND *hnd)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_FILE_ENUM q;
SRV_R_NET_FILE_ENUM r;
WERROR result = W_ERROR(ERRgeneral);
int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Initialise input parameters */
init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name,
file_level, ctr, preferred_len, hnd);
/* Marshall data and send request */
if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
if (!srv_io_r_net_file_enum("", &r, &rbuf, 0))
goto done;
result = r.status;
if (!W_ERROR_IS_OK(result))
goto done;
/* copy the data over to the ctr */
ZERO_STRUCTP(ctr);
ctr->switch_value = file_level;
ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries;
switch(file_level) {
case 3:
ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc(
mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries);
memset(ctr->file.info3, 0,
sizeof(SRV_FILE_INFO_3) * ctr->num_entries);
for (i = 0; i < r.ctr.num_entries; i++) {
SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i];
char *s;
/* Copy pointer crap */
memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3,
sizeof(FILE_INFO_3));
/* Duplicate strings */
s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name);
if (s)
init_unistr2(&info3->info_3_str.uni_path_name, s, UNI_STR_TERMINATE);
s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name);
if (s)
init_unistr2(&info3->info_3_str.uni_user_name, s, UNI_STR_TERMINATE);
}
break;
}
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 file_id)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_FILE_CLOSE q;
SRV_R_NET_FILE_CLOSE r;
WERROR result = W_ERROR(ERRgeneral);
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Initialise input parameters */
init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id);
/* Marshall data and send request */
if (!srv_io_q_net_file_close("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
if (!srv_io_r_net_file_close("", &r, &rbuf, 0))
goto done;
result = r.status;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}