2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Jelmer Vernooij 2006.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* This is the implementation of the srvsvc pipe. */
29 #define MAX_SERVER_DISK_ENTRIES 15
31 extern struct generic_mapping file_generic_mapping;
32 extern userdom_struct current_user_info;
35 #define DBGC_CLASS DBGC_RPC_SRV
37 /* Use for enumerating connections, pipes, & files */
39 struct file_enum_count {
42 struct srvsvc_NetFileInfo3 *info;
45 struct sess_file_count {
51 /****************************************************************************
52 Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
55 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
57 struct pipe_open_rec prec;
58 struct file_enum_count *fenum = (struct file_enum_count *)p;
60 if (dbuf.dsize != sizeof(struct pipe_open_rec))
63 memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
65 if ( process_exists(prec.pid) ) {
66 struct srvsvc_NetFileInfo3 *f;
70 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
72 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
74 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
80 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
81 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
82 fenum->info[i].num_locks = 0;
83 fenum->info[i].user = uidtoname( prec.uid );
84 fenum->info[i].path = fullpath;
92 /*******************************************************************
93 ********************************************************************/
95 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
96 uint32 *count, uint32 *resume )
98 struct file_enum_count fenum;
99 TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
102 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
103 return WERR_ACCESS_DENIED;
108 fenum.count = *count;
110 if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
111 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
112 tdb_errorstr(conn_tdb) ));
117 *count = fenum.count;
121 /*******************************************************************
122 ********************************************************************/
124 /* global needed to make use of the share_mode_forall() callback */
125 static struct file_enum_count f_enum_cnt;
127 static void enum_file_fn( const struct share_mode_entry *e,
128 const char *sharepath, const char *fname,
131 struct file_enum_count *fenum = &f_enum_cnt;
133 /* If the pid was not found delete the entry from connections.tdb */
135 if ( process_exists(e->pid) ) {
136 struct srvsvc_NetFileInfo3 *f;
137 int i = fenum->count;
139 struct byte_range_lock *brl;
144 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
146 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
151 /* need to count the number of locks on a file */
155 fsp.inode = e->inode;
157 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
158 num_locks = brl->num_locks;
162 if ( strcmp( fname, "." ) == 0 ) {
163 pstr_sprintf( fullpath, "C:%s", sharepath );
165 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
167 string_replace( fullpath, '/', '\\' );
169 /* mask out create (what ever that is) */
170 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
172 fenum->info[i].fid = e->share_file_id;
173 fenum->info[i].permissions = permissions;
174 fenum->info[i].num_locks = num_locks;
175 fenum->info[i].user = uidtoname(e->uid);
176 fenum->info[i].path = fullpath;
185 /*******************************************************************
186 ********************************************************************/
188 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
189 uint32 *count, uint32 *resume )
191 f_enum_cnt.ctx = ctx;
192 f_enum_cnt.count = *count;
193 f_enum_cnt.info = *info;
195 share_mode_forall( enum_file_fn, NULL );
197 *info = f_enum_cnt.info;
198 *count = f_enum_cnt.count;
203 /*******************************************************************
204 Utility function to get the 'type' of a share from a share definition.
205 ********************************************************************/
206 static uint32 get_share_type(const struct share_params *params)
208 char *net_name = lp_servicename(params->service);
209 int len_net_name = strlen(net_name);
211 /* work out the share type */
212 uint32 type = STYPE_DISKTREE;
214 if (lp_print_ok(params->service))
216 if (strequal(lp_fstype(params->service), "IPC"))
218 if (net_name[len_net_name] == '$')
219 type |= STYPE_HIDDEN;
224 /*******************************************************************
225 Fill in a share info level 0 structure.
226 ********************************************************************/
228 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
229 const struct share_params *params)
231 sh0->name = lp_servicename(params->service);
234 /*******************************************************************
235 Fill in a share info level 1 structure.
236 ********************************************************************/
238 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
239 const struct share_params *params)
241 connection_struct *conn = p->conn;
243 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
244 conn->user, conn->connectpath, conn->gid,
245 get_current_username(),
246 current_user_info.domain,
247 lp_comment(params->service));
249 sh1->name = lp_servicename(params->service);
250 sh1->type = get_share_type(params);
253 /*******************************************************************
254 Fill in a share info level 2 structure.
255 ********************************************************************/
257 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
258 const struct share_params *params)
260 connection_struct *conn = p->conn;
263 int max_connections = lp_max_connections(params->service);
264 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
266 char *net_name = lp_servicename(params->service);
268 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
269 conn->user, conn->connectpath, conn->gid,
270 get_current_username(),
271 current_user_info.domain,
272 lp_comment(params->service));
273 path = talloc_asprintf(p->mem_ctx, "C:%s",
274 lp_pathname(params->service));
277 * Change / to \\ so that win2k will see it as a valid path. This was
278 * added to enable use of browsing in win2k add share dialog.
281 string_replace(path, '/', '\\');
283 count = count_current_connections( net_name, False );
284 sh2->name = net_name;
285 sh2->type = get_share_type(params);
286 sh2->comment = remark;
287 sh2->permissions = 0;
288 sh2->max_users = max_uses;
289 sh2->current_users = count;
294 /*******************************************************************
295 Map any generic bits to file specific bits.
296 ********************************************************************/
298 static void map_generic_share_sd_bits(SEC_DESC *psd)
301 SEC_ACL *ps_dacl = NULL;
310 for (i = 0; i < ps_dacl->num_aces; i++) {
311 SEC_ACE *psa = &ps_dacl->aces[i];
312 uint32 orig_mask = psa->access_mask;
314 se_map_generic(&psa->access_mask, &file_generic_mapping);
315 psa->access_mask |= orig_mask;
319 /*******************************************************************
320 Fill in a share info level 501 structure.
321 ********************************************************************/
323 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
324 const struct share_params *params)
326 connection_struct *conn = p->conn;
328 const char *net_name = lp_servicename(params->service);
330 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
331 conn->user, conn->connectpath, conn->gid,
332 get_current_username(),
333 current_user_info.domain,
334 lp_comment(params->service));
337 sh501->name = net_name;
338 sh501->type = get_share_type(params);
339 sh501->comment = remark;
340 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
343 /*******************************************************************
344 Fill in a share info level 502 structure.
345 ********************************************************************/
347 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
348 const struct share_params *params)
350 int max_connections = lp_max_connections(params->service);
351 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
352 connection_struct *conn = p->conn;
359 TALLOC_CTX *ctx = p->mem_ctx;
364 net_name = lp_servicename(params->service);
365 count = count_current_connections( net_name, False );
367 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
368 conn->user, conn->connectpath, conn->gid,
369 get_current_username(),
370 current_user_info.domain,
371 lp_comment(params->service));
373 path = talloc_asprintf(p->mem_ctx, "C:%s",
374 lp_pathname(params->service));
377 * Change / to \\ so that win2k will see it as a valid path. This was
378 * added to enable use of browsing in win2k add share dialog.
381 string_replace(path, '/', '\\');
383 sd = get_share_security(ctx, lp_servicename(params->service),
386 sh502->name = net_name;
387 sh502->type = get_share_type(params);
388 sh502->comment = remark;
390 sh502->password = "";
392 sh502->permissions = 0;
393 sh502->max_users = max_uses;
394 sh502->current_users = count;
398 /***************************************************************************
399 Fill in a share info level 1004 structure.
400 ***************************************************************************/
402 static void init_srv_share_info_1004(pipes_struct *p,
403 struct srvsvc_NetShareInfo1004* sh1004,
404 const struct share_params *params)
406 connection_struct *conn = p->conn;
409 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
410 conn->user, conn->connectpath, conn->gid,
411 get_current_username(),
412 current_user_info.domain,
413 lp_comment(params->service));
415 ZERO_STRUCTP(sh1004);
417 sh1004->comment = remark;
420 /***************************************************************************
421 Fill in a share info level 1005 structure.
422 ***************************************************************************/
424 static void init_srv_share_info_1005(pipes_struct *p,
425 struct srvsvc_NetShareInfo1005* sh1005,
426 const struct share_params *params)
428 sh1005->dfs_flags = 0;
430 if(lp_host_msdfs() && lp_msdfs_root(params->service))
432 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
434 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
436 /***************************************************************************
437 Fill in a share info level 1006 structure.
438 ***************************************************************************/
440 static void init_srv_share_info_1006(pipes_struct *p,
441 struct srvsvc_NetShareInfo1006* sh1006,
442 const struct share_params *params)
444 sh1006->max_users = -1;
447 /***************************************************************************
448 Fill in a share info level 1007 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1007(pipes_struct *p,
452 struct srvsvc_NetShareInfo1007* sh1007,
453 const struct share_params *params)
457 ZERO_STRUCTP(sh1007);
459 sh1007->flags = flags;
460 sh1007->alternate_directory_name = "";
463 /*******************************************************************
464 Fill in a share info level 1501 structure.
465 ********************************************************************/
467 static void init_srv_share_info_1501(pipes_struct *p,
468 struct sec_desc_buf *sh1501,
469 const struct share_params *params)
473 TALLOC_CTX *ctx = p->mem_ctx;
475 ZERO_STRUCTP(sh1501);
477 sd = get_share_security(ctx, lp_servicename(params->service),
483 /*******************************************************************
484 True if it ends in '$'.
485 ********************************************************************/
487 static BOOL is_hidden_share(const struct share_params *params)
489 const char *net_name = lp_servicename(params->service);
491 return (net_name[strlen(net_name) - 1] == '$');
494 /*******************************************************************
495 Fill in a share info structure.
496 ********************************************************************/
498 static WERROR init_srv_share_info_ctr(pipes_struct *p,
499 union srvsvc_NetShareCtr *ctr,
500 uint32 info_level, uint32 *resume_hnd,
501 uint32 *total_entries, BOOL all_shares)
503 TALLOC_CTX *ctx = p->mem_ctx;
504 struct share_iterator *shares;
505 struct share_params *share;
507 DEBUG(5,("init_srv_share_info_ctr\n"));
515 /* Ensure all the usershares are loaded. */
517 load_usershare_shares();
522 if (!(shares = share_list_all(ctx))) {
523 DEBUG(5, ("Could not list shares\n"));
524 return WERR_ACCESS_DENIED;
527 switch (info_level) {
529 ctr->ctr0 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr0);
532 ctr->ctr1 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1);
535 ctr->ctr2 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr2);
538 ctr->ctr501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr501);
541 ctr->ctr502 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr502);
544 ctr->ctr1004 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1004);
547 ctr->ctr1005 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1005);
550 ctr->ctr1006 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1006);
553 ctr->ctr1007 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1007);
556 ctr->ctr1501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1501);
559 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
560 "value %d\n", info_level));
561 return WERR_UNKNOWN_LEVEL;
564 while ((share = next_share(shares)) != NULL) {
565 if (!lp_browseable(share->service)) {
568 if (!all_shares && is_hidden_share(share)) {
572 switch (info_level) {
575 struct srvsvc_NetShareInfo0 i;
576 init_srv_share_info_0(p, &i, share);
577 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
578 &ctr->ctr0->array, &ctr->ctr0->count);
579 if (ctr->ctr0->array == NULL) {
582 *total_entries = ctr->ctr0->count;
588 struct srvsvc_NetShareInfo1 i;
589 init_srv_share_info_1(p, &i, share);
590 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
591 &ctr->ctr1->array, &ctr->ctr1->count);
592 if (ctr->ctr1->array == NULL) {
595 *total_entries = ctr->ctr1->count;
601 struct srvsvc_NetShareInfo2 i;
602 init_srv_share_info_2(p, &i, share);
603 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
604 &ctr->ctr2->array, &ctr->ctr2->count);
605 if (ctr->ctr2->array == NULL) {
608 *total_entries = ctr->ctr2->count;
614 struct srvsvc_NetShareInfo501 i;
615 init_srv_share_info_501(p, &i, share);
616 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
617 &ctr->ctr501->array, &ctr->ctr501->count);
618 if (ctr->ctr501->array == NULL) {
621 *total_entries = ctr->ctr501->count;
627 struct srvsvc_NetShareInfo502 i;
628 init_srv_share_info_502(p, &i, share);
629 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
630 &ctr->ctr502->array, &ctr->ctr502->count);
631 if (ctr->ctr502->array == NULL) {
634 *total_entries = ctr->ctr502->count;
638 /* here for completeness but not currently used with enum
643 struct srvsvc_NetShareInfo1004 i;
644 init_srv_share_info_1004(p, &i, share);
645 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
646 &ctr->ctr1004->array, &ctr->ctr1004->count);
647 if (ctr->ctr1004->array == NULL) {
650 *total_entries = ctr->ctr1004->count;
656 struct srvsvc_NetShareInfo1005 i;
657 init_srv_share_info_1005(p, &i, share);
658 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
659 &ctr->ctr1005->array, &ctr->ctr1005->count);
660 if (ctr->ctr1005->array == NULL) {
663 *total_entries = ctr->ctr1005->count;
669 struct srvsvc_NetShareInfo1006 i;
670 init_srv_share_info_1006(p, &i, share);
671 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
672 &ctr->ctr1006->array, &ctr->ctr1006->count);
673 if (ctr->ctr1006->array == NULL) {
676 *total_entries = ctr->ctr1006->count;
682 struct srvsvc_NetShareInfo1007 i;
683 init_srv_share_info_1007(p, &i, share);
684 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
685 &ctr->ctr1007->array, &ctr->ctr1007->count);
686 if (ctr->ctr1007->array == NULL) {
689 *total_entries = ctr->ctr1007->count;
695 struct sec_desc_buf i;
696 init_srv_share_info_1501(p, &i, share);
697 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
698 &ctr->ctr1501->array, &ctr->ctr1501->count);
699 if (ctr->ctr1501->array == NULL) {
702 *total_entries = ctr->ctr1501->count;
713 /*******************************************************************
714 fill in a sess info level 0 structure.
715 ********************************************************************/
717 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
719 struct sessionid *session_list;
720 uint32 num_entries = 0;
721 (*stot) = list_sessions(&session_list);
727 SAFE_FREE(session_list);
731 DEBUG(5,("init_srv_sess_0_ss0\n"));
733 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
736 for (; (*snum) < (*stot); (*snum)++) {
737 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
741 ss0->count = num_entries;
743 if ((*snum) >= (*stot)) {
751 SAFE_FREE(session_list);
754 /*******************************************************************
755 ********************************************************************/
757 static void sess_file_fn( const struct share_mode_entry *e,
758 const char *sharepath, const char *fname,
761 struct sess_file_count *sess = (struct sess_file_count *)private_data;
763 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
770 /*******************************************************************
771 ********************************************************************/
773 static int net_count_files( uid_t uid, pid_t pid )
775 struct sess_file_count s_file_cnt;
777 s_file_cnt.count = 0;
778 s_file_cnt.uid = uid;
779 s_file_cnt.pid = pid;
781 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
783 return s_file_cnt.count;
786 /*******************************************************************
787 fill in a sess info level 1 structure.
788 ********************************************************************/
790 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
792 struct sessionid *session_list;
793 uint32 num_entries = 0;
794 time_t now = time(NULL);
811 (*stot) = list_sessions(&session_list);
813 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
815 for (; (*snum) < (*stot); (*snum)++) {
818 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
822 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
823 session_list[*snum].username));
827 connect_time = (uint32)(now - session_list[*snum].connect_start);
828 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
829 guest = strequal( session_list[*snum].username, lp_guestaccount() );
831 ss1->array[num_entries].client = session_list[*snum].remote_machine;
832 ss1->array[num_entries].user = session_list[*snum].username;
833 ss1->array[num_entries].num_open = num_files;
834 ss1->array[num_entries].time = connect_time;
835 ss1->array[num_entries].idle_time = 0;
836 ss1->array[num_entries].user_flags = guest;
841 ss1->count = num_entries;
843 if ((*snum) >= (*stot)) {
847 SAFE_FREE(session_list);
850 /*******************************************************************
851 makes a SRV_R_NET_SESS_ENUM structure.
852 ********************************************************************/
854 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
855 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
857 WERROR status = WERR_OK;
858 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
860 switch (switch_value) {
862 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
863 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
866 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
867 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
870 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
871 if (resume_hnd != NULL)
873 (*total_entries) = 0;
875 status = WERR_UNKNOWN_LEVEL;
882 /*******************************************************************
883 fill in a conn info level 0 structure.
884 ********************************************************************/
886 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
888 uint32 num_entries = 0;
897 DEBUG(5,("init_srv_conn_0_ss0\n"));
900 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
901 for (; (*snum) < (*stot); (*snum)++) {
903 ss0->array[num_entries].conn_id = (*stot);
905 /* move on to creating next connection */
906 /* move on to creating next conn */
910 ss0->count = num_entries;
912 if ((*snum) >= (*stot)) {
924 /*******************************************************************
925 fill in a conn info level 1 structure.
926 ********************************************************************/
928 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
930 uint32 num_entries = 0;
939 DEBUG(5,("init_srv_conn_1_ss1\n"));
942 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
943 for (; (*snum) < (*stot); (*snum)++) {
944 ss1->array[num_entries].conn_id = (*stot);
945 ss1->array[num_entries].conn_type = 0x3;
946 ss1->array[num_entries].num_open = 1;
947 ss1->array[num_entries].num_users = 1;
948 ss1->array[num_entries].conn_time = 3;
949 ss1->array[num_entries].user = "dummy_user";
950 ss1->array[num_entries].share = "IPC$";
952 /* move on to creating next connection */
953 /* move on to creating next conn */
957 ss1->count = num_entries;
959 if ((*snum) >= (*stot)) {
971 /*******************************************************************
972 makes a SRV_R_NET_CONN_ENUM structure.
973 ********************************************************************/
975 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
976 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
978 WERROR status = WERR_OK;
979 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
981 switch (switch_value) {
983 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
986 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
989 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
992 (*total_entries) = 0;
993 status = WERR_UNKNOWN_LEVEL;
1000 /*******************************************************************
1001 makes a SRV_R_NET_FILE_ENUM structure.
1002 ********************************************************************/
1004 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1006 TALLOC_CTX *ctx = get_talloc_ctx();
1009 /* TODO -- Windows enumerates
1011 (c) open directories and files */
1013 ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1015 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1016 if ( !W_ERROR_IS_OK(status))
1019 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1020 if ( !W_ERROR_IS_OK(status))
1023 ctr->ctr3->count = *num_entries;
1028 /*******************************************************************
1029 *******************************************************************/
1031 WERROR _srvsvc_NetFileEnum(pipes_struct *p, const char *server_unc, const char *path, const char *user, uint32_t *level, union srvsvc_NetFileCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1035 return net_file_enum_3(p, ctr, resume_handle, totalentries );
1037 return WERR_UNKNOWN_LEVEL;
1043 /*******************************************************************
1045 ********************************************************************/
1047 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo *info)
1049 WERROR status = WERR_OK;
1053 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1055 if (!pipe_access_check(p)) {
1056 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1057 return WERR_ACCESS_DENIED;
1062 /* Technically level 102 should only be available to
1063 Administrators but there isn't anything super-secret
1064 here, as most of it is made up. */
1067 info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1069 info->info102->platform_id = 500;
1070 info->info102->version_major = lp_major_announce_version();
1071 info->info102->version_minor = lp_minor_announce_version();
1072 info->info102->server_name = global_myname();
1073 info->info102->server_type = lp_default_server_announce();
1074 info->info102->userpath = "C:\\";
1075 info->info102->licenses = 10000;
1076 info->info102->anndelta = 3000;
1077 info->info102->disc = 0xf;
1078 info->info102->users = 0xffffffff;
1079 info->info102->hidden = 0;
1080 info->info102->announce = 240;
1081 info->info102->comment = lp_serverstring();
1084 info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1085 info->info101->platform_id = 500;
1086 info->info101->server_name = global_myname();
1087 info->info101->version_major = lp_major_announce_version();
1088 info->info101->version_minor = lp_minor_announce_version();
1089 info->info101->server_type = lp_default_server_announce();
1090 info->info101->comment = lp_serverstring();
1093 info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1094 info->info100->platform_id = 500;
1095 info->info100->server_name = global_myname();
1098 return WERR_UNKNOWN_LEVEL;
1102 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1107 /*******************************************************************
1109 ********************************************************************/
1111 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo info, uint32_t *parm_error)
1113 /* Set up the net server set info structure. */
1118 /*******************************************************************
1120 ********************************************************************/
1122 WERROR _srvsvc_NetConnEnum(pipes_struct *p, const char *server_unc, const char *path, uint32_t *level, union srvsvc_NetConnCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1124 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1129 return init_srv_conn_info_ctr(p, ctr, *level, resume_handle, totalentries);
1132 /*******************************************************************
1134 ********************************************************************/
1136 WERROR _srvsvc_NetSessEnum(pipes_struct *p, const char *server_unc, const char *client, const char *user, uint32_t *level, union srvsvc_NetSessCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1138 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1143 return init_srv_sess_info_ctr(p, ctr,
1149 /*******************************************************************
1151 ********************************************************************/
1153 WERROR _srvsvc_NetSessDel(pipes_struct *p, const char *server_unc, const char *client, const char *user)
1155 struct sessionid *session_list;
1156 int num_sessions, snum;
1159 char *machine = talloc_strdup(p->mem_ctx, server_unc);
1161 /* strip leading backslashes if any */
1162 while (machine[0] == '\\') {
1163 memmove(machine, &machine[1], strlen(machine));
1166 num_sessions = list_sessions(&session_list);
1168 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1170 status = WERR_ACCESS_DENIED;
1172 /* fail out now if you are not root or not a domain admin */
1174 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1175 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1180 for (snum = 0; snum < num_sessions; snum++) {
1182 if ((strequal(session_list[snum].username, user) || user[0] == '\0' ) &&
1183 strequal(session_list[snum].remote_machine, machine)) {
1185 if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1190 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1194 SAFE_FREE(session_list);
1199 /*******************************************************************
1201 ********************************************************************/
1203 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetShareCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1205 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1207 if (!pipe_access_check(p)) {
1208 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1209 return WERR_ACCESS_DENIED;
1212 /* Create the list of shares for the response. */
1213 return init_srv_share_info_ctr(p, ctr, *level,
1214 resume_handle, totalentries, True);
1217 /*******************************************************************
1219 ********************************************************************/
1221 WERROR _srvsvc_NetShareEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetShareCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1223 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1225 if (!pipe_access_check(p)) {
1226 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1227 return WERR_ACCESS_DENIED;
1230 /* Create the list of shares for the response. */
1231 return init_srv_share_info_ctr(p, ctr, *level,
1232 resume_handle, totalentries, False);
1235 /*******************************************************************
1237 ********************************************************************/
1239 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo *info)
1241 const struct share_params *params;
1243 params = get_share_params(p->mem_ctx, share_name);
1245 if (params != NULL) {
1248 info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1249 init_srv_share_info_0(p, info->info0,
1253 info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1254 init_srv_share_info_1(p, info->info1,
1258 info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1259 init_srv_share_info_2(p, info->info2,
1263 info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1264 init_srv_share_info_501(p, info->info501,
1268 info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1269 init_srv_share_info_502(p, info->info502,
1273 /* here for completeness */
1275 info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1276 init_srv_share_info_1004(p, info->info1004,
1280 info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1281 init_srv_share_info_1005(p, info->info1005,
1285 /* here for completeness 1006 - 1501 */
1287 info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1288 init_srv_share_info_1006(p, info->info1006,
1292 info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1293 init_srv_share_info_1007(p, info->info1007,
1297 info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1298 init_srv_share_info_1501(p, info->info1501,
1302 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1303 "switch value %d\n", level));
1304 return WERR_UNKNOWN_LEVEL;
1308 return WERR_INVALID_NAME;
1314 /*******************************************************************
1315 Check a given DOS pathname is valid for a share.
1316 ********************************************************************/
1318 char *valid_share_pathname(char *dos_pathname)
1322 /* Convert any '\' paths to '/' */
1323 unix_format(dos_pathname);
1324 unix_clean_name(dos_pathname);
1326 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1328 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1331 /* Only absolute paths allowed. */
1338 /*******************************************************************
1339 Net share set info. Modify share details.
1340 ********************************************************************/
1342 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1351 SEC_DESC *psd = NULL;
1352 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1353 BOOL is_disk_op = False;
1354 int max_connections = 0;
1355 fstring tmp_share_name;
1357 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1361 if ( strequal(share_name,"IPC$")
1362 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1363 || strequal(share_name,"global") )
1365 return WERR_ACCESS_DENIED;
1368 fstrcpy(tmp_share_name, share_name);
1369 snum = find_service(tmp_share_name);
1371 /* Does this share exist ? */
1373 return WERR_NET_NAME_NOT_FOUND;
1375 /* No change to printer shares. */
1376 if (lp_print_ok(snum))
1377 return WERR_ACCESS_DENIED;
1379 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1381 /* fail out now if you are not root and not a disk op */
1383 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1384 return WERR_ACCESS_DENIED;
1388 pstrcpy(pathname, lp_pathname(snum));
1389 pstrcpy(comment, info.info1->comment);
1390 type = info.info1->type;
1394 pstrcpy(comment, info.info2->comment);
1395 pstrcpy(pathname, info.info2->path);
1396 type = info.info2->type;
1397 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1401 /* not supported on set but here for completeness */
1403 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1404 type = q_u->info.share.info501.info_501.type;
1409 pstrcpy(comment, info.info502->comment);
1410 pstrcpy(pathname, info.info502->path);
1411 type = info.info502->type;
1412 psd = info.info502->sd;
1413 map_generic_share_sd_bits(psd);
1416 pstrcpy(pathname, lp_pathname(snum));
1417 pstrcpy(comment, info.info1004->comment);
1418 type = STYPE_DISKTREE;
1421 /* XP re-sets the csc policy even if it wasn't changed by the
1422 user, so we must compare it to see if it's what is set in
1423 smb.conf, so that we can contine other ops like setting
1425 if (((info.info1005->dfs_flags &
1426 SHARE_1005_CSC_POLICY_MASK) >>
1427 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1430 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1431 return WERR_ACCESS_DENIED;
1435 return WERR_ACCESS_DENIED;
1437 pstrcpy(pathname, lp_pathname(snum));
1438 pstrcpy(comment, lp_comment(snum));
1439 psd = info.info1501->sd;
1440 map_generic_share_sd_bits(psd);
1441 type = STYPE_DISKTREE;
1444 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", level));
1445 return WERR_UNKNOWN_LEVEL;
1448 /* We can only modify disk shares. */
1449 if (type != STYPE_DISKTREE)
1450 return WERR_ACCESS_DENIED;
1452 /* Check if the pathname is valid. */
1453 if (!(path = valid_share_pathname( pathname )))
1454 return WERR_OBJECT_PATH_INVALID;
1456 /* Ensure share name, pathname and comment don't contain '"' characters. */
1457 string_replace(tmp_share_name, '"', ' ');
1458 string_replace(path, '"', ' ');
1459 string_replace(comment, '"', ' ');
1461 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1462 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1464 /* Only call modify function if something changed. */
1466 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1467 || (lp_max_connections(snum) != max_connections) )
1469 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1470 DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1471 return WERR_ACCESS_DENIED;
1474 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1475 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1477 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1479 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1484 if ( (ret = smbrun(command, NULL)) == 0 ) {
1485 /* Tell everyone we updated smb.conf. */
1486 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1492 /********* END SeDiskOperatorPrivilege BLOCK *********/
1494 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1497 return WERR_ACCESS_DENIED;
1499 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1502 /* Replace SD if changed. */
1507 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1510 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1511 if (!set_share_security(p->mem_ctx, share_name, psd))
1512 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1517 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1522 /*******************************************************************
1523 Net share add. Call 'add_share_command "sharename" "pathname"
1524 "comment" "max connections = "
1525 ********************************************************************/
1527 WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1537 SEC_DESC *psd = NULL;
1538 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1540 int max_connections = 0;
1542 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1546 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1548 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1549 return WERR_ACCESS_DENIED;
1551 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1552 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1553 return WERR_ACCESS_DENIED;
1558 /* No path. Not enough info in a level 0 to do anything. */
1559 return WERR_ACCESS_DENIED;
1561 /* Not enough info in a level 1 to do anything. */
1562 return WERR_ACCESS_DENIED;
1564 pstrcpy(share_name, info.info2->name);
1565 pstrcpy(comment, info.info2->comment);
1566 pstrcpy(pathname, info.info2->path);
1567 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1568 type = info.info2->type;
1571 /* No path. Not enough info in a level 501 to do anything. */
1572 return WERR_ACCESS_DENIED;
1574 pstrcpy(share_name, info.info502->name);
1575 pstrcpy(comment, info.info502->comment);
1576 pstrcpy(pathname, info.info502->path);
1577 type = info.info502->type;
1578 psd = info.info502->sd;
1579 map_generic_share_sd_bits(psd);
1582 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1588 return WERR_ACCESS_DENIED;
1590 /* DFS only level. */
1591 return WERR_ACCESS_DENIED;
1593 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", level));
1594 return WERR_UNKNOWN_LEVEL;
1597 /* check for invalid share names */
1599 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1600 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1601 return WERR_INVALID_NAME;
1604 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1605 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1607 return WERR_ACCESS_DENIED;
1610 snum = find_service(share_name);
1612 /* Share already exists. */
1614 return WERR_ALREADY_EXISTS;
1616 /* We can only add disk shares. */
1617 if (type != STYPE_DISKTREE)
1618 return WERR_ACCESS_DENIED;
1620 /* Check if the pathname is valid. */
1621 if (!(path = valid_share_pathname( pathname )))
1622 return WERR_OBJECT_PATH_INVALID;
1624 /* Ensure share name, pathname and comment don't contain '"' characters. */
1625 string_replace(share_name, '"', ' ');
1626 string_replace(path, '"', ' ');
1627 string_replace(comment, '"', ' ');
1629 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1637 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1639 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1644 if ( (ret = smbrun(command, NULL)) == 0 ) {
1645 /* Tell everyone we updated smb.conf. */
1646 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1652 /********* END SeDiskOperatorPrivilege BLOCK *********/
1654 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1657 return WERR_ACCESS_DENIED;
1660 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1661 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1666 * We don't call reload_services() here, the message will
1667 * cause this to be done before the next packet is read
1668 * from the client. JRA.
1671 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1676 /*******************************************************************
1677 Net share delete. Call "delete share command" with the share name as
1679 ********************************************************************/
1681 WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1685 struct share_params *params;
1686 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1689 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1691 if ( strequal(share_name,"IPC$")
1692 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1693 || strequal(share_name,"global") )
1695 return WERR_ACCESS_DENIED;
1698 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1699 return WERR_NO_SUCH_SHARE;
1702 /* No change to printer shares. */
1703 if (lp_print_ok(params->service))
1704 return WERR_ACCESS_DENIED;
1706 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1708 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1709 return WERR_ACCESS_DENIED;
1711 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1712 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1713 return WERR_ACCESS_DENIED;
1716 if (asprintf(&command, "%s \"%s\" \"%s\"",
1717 lp_delete_share_cmd(), dyn_CONFIGFILE,
1718 lp_servicename(params->service)) == -1) {
1722 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1724 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1729 if ( (ret = smbrun(command, NULL)) == 0 ) {
1730 /* Tell everyone we updated smb.conf. */
1731 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1739 /********* END SeDiskOperatorPrivilege BLOCK *********/
1741 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1744 return WERR_ACCESS_DENIED;
1746 /* Delete the SD in the database. */
1747 delete_share_security(params);
1749 lp_killservice(params->service);
1754 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1756 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1758 return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1761 /*******************************************************************
1763 ********************************************************************/
1765 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1768 time_t unixdate = time(NULL);
1769 WERROR status = WERR_OK;
1771 /* We do this call first as if we do it *after* the gmtime call
1772 it overwrites the pointed-to values. JRA */
1774 uint32 zone = get_time_zone(unixdate)/60;
1776 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1778 t = gmtime(&unixdate);
1781 tod->elapsed = unixdate;
1783 tod->hours = t->tm_hour;
1784 tod->mins = t->tm_min;
1785 tod->secs = t->tm_sec;
1787 tod->timezone = zone;
1788 tod->tinterval = 10000;
1789 tod->day = t->tm_mday;
1790 tod->month = t->tm_mon + 1;
1791 tod->year = 1900+t->tm_year;
1792 tod->weekday = t->tm_wday;
1794 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1799 /***********************************************************************************
1800 Win9x NT tools get security descriptor.
1801 ***********************************************************************************/
1803 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, const char *server_unc, const char *share, const char *file, uint32_t securityinformation, struct sec_desc_buf *sd_buf)
1805 SEC_DESC *psd = NULL;
1808 files_struct *fsp = NULL;
1812 connection_struct *conn = NULL;
1813 BOOL became_user = False;
1814 WERROR status = WERR_OK;
1820 /* Null password is ok - we are already an authenticated user... */
1821 null_pw = data_blob(NULL, 0);
1824 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1828 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
1829 status = ntstatus_to_werror(nt_status);
1833 if (!become_user(conn, conn->vuid)) {
1834 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1835 status = WERR_ACCESS_DENIED;
1840 pstrcpy(tmp_file, file);
1841 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1843 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
1844 status = WERR_ACCESS_DENIED;
1848 if (!check_name(file,conn)) {
1849 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
1850 status = WERR_ACCESS_DENIED;
1854 nt_status = open_file_stat(conn, file, &st, &fsp);
1855 if (!NT_STATUS_IS_OK(nt_status)) {
1856 /* Perhaps it is a directory */
1857 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1858 nt_status = open_directory(conn, file, &st,
1859 READ_CONTROL_ACCESS,
1860 FILE_SHARE_READ|FILE_SHARE_WRITE,
1865 if (!NT_STATUS_IS_OK(nt_status)) {
1866 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
1867 status = WERR_ACCESS_DENIED;
1872 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1875 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
1876 status = WERR_ACCESS_DENIED;
1880 sd_buf->sd_size= sd_size;
1883 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1885 close_file(fsp, NORMAL_CLOSE);
1887 close_cnum(conn, p->pipe_user.vuid);
1893 close_file(fsp, NORMAL_CLOSE);
1900 close_cnum(conn, p->pipe_user.vuid);
1905 /***********************************************************************************
1906 Win9x NT tools set security descriptor.
1907 ***********************************************************************************/
1909 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, const char *server_unc, const char *share, const char *file, uint32_t securityinformation, struct sec_desc_buf sd_buf)
1913 files_struct *fsp = NULL;
1917 connection_struct *conn = NULL;
1918 BOOL became_user = False;
1919 WERROR status = WERR_OK;
1924 /* Null password is ok - we are already an authenticated user... */
1925 null_pw = data_blob(NULL, 0);
1928 conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1932 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
1933 status = ntstatus_to_werror(nt_status);
1937 if (!become_user(conn, conn->vuid)) {
1938 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1939 status = WERR_ACCESS_DENIED;
1944 pstrcpy(tmp_file, file);
1945 unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1947 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
1948 status = WERR_ACCESS_DENIED;
1952 if (!check_name(file,conn)) {
1953 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
1954 status = WERR_ACCESS_DENIED;
1959 nt_status = open_file_stat(conn, file, &st, &fsp);
1961 if (!NT_STATUS_IS_OK(nt_status)) {
1962 /* Perhaps it is a directory */
1963 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1964 nt_status = open_directory(conn, file, &st,
1965 FILE_READ_ATTRIBUTES,
1966 FILE_SHARE_READ|FILE_SHARE_WRITE,
1971 if (!NT_STATUS_IS_OK(nt_status)) {
1972 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
1973 status = WERR_ACCESS_DENIED;
1978 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
1981 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
1982 status = WERR_ACCESS_DENIED;
1986 close_file(fsp, NORMAL_CLOSE);
1988 close_cnum(conn, p->pipe_user.vuid);
1994 close_file(fsp, NORMAL_CLOSE);
2002 close_cnum(conn, p->pipe_user.vuid);
2008 /***********************************************************************************
2009 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2010 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2011 These disks would the disks listed by this function.
2012 Users could then create shares relative to these disks. Watch out for moving these disks around.
2013 "Nigel Williams" <nigel@veritas.com>.
2014 ***********************************************************************************/
2016 static const char *server_disks[] = {"C:"};
2018 static uint32 get_server_disk_count(void)
2020 return sizeof(server_disks)/sizeof(server_disks[0]);
2023 static uint32 init_server_disk_enum(uint32 *resume)
2025 uint32 server_disk_count = get_server_disk_count();
2027 /*resume can be an offset into the list for now*/
2029 if(*resume & 0x80000000)
2032 if(*resume > server_disk_count)
2033 *resume = server_disk_count;
2035 return server_disk_count - *resume;
2038 static const char *next_server_disk_enum(uint32 *resume)
2042 if(init_server_disk_enum(resume) == 0)
2045 disk = server_disks[*resume];
2049 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2054 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, const char *server_unc, uint32_t level, struct srvsvc_NetDiskInfo *info, uint32_t maxlen, uint32_t *totalentries, uint32_t *resume_handle)
2057 const char *disk_name;
2059 WERROR status = WERR_OK;
2061 *totalentries = init_server_disk_enum(resume_handle);
2064 if(!(info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2068 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2070 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2075 /*copy disk name into a unicode string*/
2077 info->disks[i].disk = disk_name;
2080 /* add a terminating null string. Is this there if there is more data to come? */
2085 info->disks[i].disk = "";
2090 /********************************************************************
2091 ********************************************************************/
2093 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2097 if ((flags != 0x0) && (flags != 0x80000000)) {
2098 return WERR_INVALID_PARAM;
2101 switch ( name_type ) {
2103 len = strlen_m(name);
2105 if ((flags == 0x0) && (len > 81)) {
2106 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2107 return WERR_INVALID_NAME;
2109 if ((flags == 0x80000000) && (len > 13)) {
2110 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2111 return WERR_INVALID_NAME;
2114 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2115 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2116 return WERR_INVALID_NAME;
2121 return WERR_UNKNOWN_LEVEL;
2128 /********************************************************************
2129 ********************************************************************/
2131 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2133 return WERR_ACCESS_DENIED;
2136 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetCharDevCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2138 p->rng_fault_state = True;
2139 return WERR_NOT_SUPPORTED;
2142 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2144 p->rng_fault_state = True;
2145 return WERR_NOT_SUPPORTED;
2148 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2150 p->rng_fault_state = True;
2151 return WERR_NOT_SUPPORTED;
2154 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, const char *server_unc, const char *user, uint32_t *level, union srvsvc_NetCharDevQCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2156 p->rng_fault_state = True;
2157 return WERR_NOT_SUPPORTED;
2160 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2162 p->rng_fault_state = True;
2163 return WERR_NOT_SUPPORTED;
2166 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, uint32_t level, union srvsvc_NetCharDevQInfo info, uint32_t *parm_error)
2168 p->rng_fault_state = True;
2169 return WERR_NOT_SUPPORTED;
2172 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2174 p->rng_fault_state = True;
2175 return WERR_NOT_SUPPORTED;
2178 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2180 p->rng_fault_state = True;
2181 return WERR_NOT_SUPPORTED;
2184 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2186 p->rng_fault_state = True;
2187 return WERR_NOT_SUPPORTED;
2190 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2192 p->rng_fault_state = True;
2193 return WERR_NOT_SUPPORTED;
2196 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2198 p->rng_fault_state = True;
2199 return WERR_NOT_SUPPORTED;
2202 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2204 p->rng_fault_state = True;
2205 return WERR_NOT_SUPPORTED;
2208 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetTransportCtr *transports, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2210 p->rng_fault_state = True;
2211 return WERR_NOT_SUPPORTED;
2214 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2216 p->rng_fault_state = True;
2217 return WERR_NOT_SUPPORTED;
2220 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2222 p->rng_fault_state = True;
2223 return WERR_NOT_SUPPORTED;
2226 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2228 p->rng_fault_state = True;
2229 return WERR_NOT_SUPPORTED;
2232 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, const char *server_unc, const char *path, uint8_t *can_path, uint32_t maxbuf, const char *prefix, uint32_t *pathtype, uint32_t pathflags)
2234 p->rng_fault_state = True;
2235 return WERR_NOT_SUPPORTED;
2238 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2240 p->rng_fault_state = True;
2241 return WERR_NOT_SUPPORTED;
2244 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2246 p->rng_fault_state = True;
2247 return WERR_NOT_SUPPORTED;
2250 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2252 p->rng_fault_state = True;
2253 return WERR_NOT_SUPPORTED;
2256 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2258 p->rng_fault_state = True;
2259 return WERR_NOT_SUPPORTED;
2262 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2264 p->rng_fault_state = True;
2265 return WERR_NOT_SUPPORTED;
2268 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2270 p->rng_fault_state = True;
2271 return WERR_NOT_SUPPORTED;
2274 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, const char *server_unc, const char *emulated_server_unc, const char *transport, uint32_t servicebitsofinterest, uint32_t servicebits, uint32_t updateimmediately)
2276 p->rng_fault_state = True;
2277 return WERR_NOT_SUPPORTED;
2280 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2282 p->rng_fault_state = True;
2283 return WERR_NOT_SUPPORTED;
2286 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2288 p->rng_fault_state = True;
2289 return WERR_NOT_SUPPORTED;
2292 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2294 p->rng_fault_state = True;
2295 return WERR_NOT_SUPPORTED;
2298 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2300 p->rng_fault_state = True;
2301 return WERR_NOT_SUPPORTED;
2304 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2306 p->rng_fault_state = True;
2307 return WERR_NOT_SUPPORTED;
2310 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2312 p->rng_fault_state = True;
2313 return WERR_NOT_SUPPORTED;
2316 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2318 p->rng_fault_state = True;
2319 return WERR_NOT_SUPPORTED;
2322 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2324 p->rng_fault_state = True;
2325 return WERR_NOT_SUPPORTED;
2328 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2330 p->rng_fault_state = True;
2331 return WERR_NOT_SUPPORTED;
2334 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2336 p->rng_fault_state = True;
2337 return WERR_NOT_SUPPORTED;
2340 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2342 p->rng_fault_state = True;
2343 return WERR_NOT_SUPPORTED;