From 2bde98c0ee67b4c60c5906b3b2f297cf4922c67c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Dec 2003 22:24:33 +0000 Subject: the rest of the initial rpc server side infrastructure (This used to be commit 5fb01b0ec0321724c25669151ea7c20e6ec182d0) --- source4/Makefile.in | 34 ++------ source4/include/context.h | 2 + source4/include/includes.h | 51 ----------- source4/include/smb.h | 1 + source4/librpc/rpc/dcerpc_smb.c | 2 +- source4/ntvfs/ipc/vfs_ipc.c | 182 +++++++++++++++++++++++++++++++++++++++- source4/smbd/process.c | 3 + 7 files changed, 195 insertions(+), 80 deletions(-) diff --git a/source4/Makefile.in b/source4/Makefile.in index 85d51de58d..c0e6466186 100644 --- a/source4/Makefile.in +++ b/source4/Makefile.in @@ -284,6 +284,9 @@ NTVFS_POSIX_OBJ = ntvfs/posix/vfs_posix.o SMBD_NTVFS_OBJ = ntvfs/ntvfs_base.o ntvfs/ntvfs_util.o \ ntvfs/ntvfs_generic.o @NTVFS_STATIC@ +SMBD_RPC_OBJ = rpc_server/dcerpc_server.o \ + rpc_server/rpc_echo.o + SMBD_OBJ_SRV = smbd/connection.o \ smbd/session.o \ smbd/password.o smbd/conn.o \ @@ -292,7 +295,7 @@ SMBD_OBJ_SRV = smbd/connection.o \ smbd/trans2.o smbd/search.o smbd/nttrans.o \ lib/sysacls.o lib/server_mutex.o \ smbd/build_options.o smbd/service.o \ - smbd/rewrite.o \ + smbd/rewrite.o $(SMBD_RPC_OBJ) \ $(SMBD_NTVFS_OBJ) @SMBD_EXTRA_OBJS@ PROCESS_MODEL_OBJ = smbd/process.o smbd/process_model.o smbd/process_standard.o \ @@ -395,7 +398,7 @@ LIBSMBCLIENT_OBJ = libcli/libcliclient.o libcli/libcli_compat.o \ LIBBIGBALLOFMUD_MAJOR = 0 LIBBIGBALLOFMUD_OBJ = $(LIB_OBJ) $(PARAM_OBJ) $(SECRETS_OBJ) \ - $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \ + $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \ $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.po) @@ -414,7 +417,6 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \ NET_OBJ = $(NET_OBJ1) $(SECRETS_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(PARAM_OBJ) $(LIB_OBJ) \ - $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ @@ -487,20 +489,10 @@ LOCKTEST2_OBJ = torture/locktest2.o $(LOCKING_OBJ) $(LIBSMB_OBJ) \ SMBCACLS_OBJ = utils/smbcacls.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ $(PARAM_OBJ) \ $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \ - $(LIBMSRPC_OBJ) $(SECRETS_OBJ) + $(SECRETS_OBJ) TALLOCTORT_OBJ = lib/talloctort.o $(LIB_OBJ) $(PARAM_OBJ) -RPCTORTURE_OBJ = torture/rpctorture.o \ - rpcclient/display.o \ - rpcclient/cmd_lsarpc.o \ - rpcclient/cmd_wkssvc.o \ - rpcclient/cmd_samr.o \ - rpcclient/cmd_srvsvc.o \ - rpcclient/cmd_netlogon.o \ - $(PARAM_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \ - $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) - DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o SMBFILTER_OBJ = utils/smbfilter.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ @@ -510,8 +502,7 @@ PROTO_OBJ = $(SMBD_OBJ_SRV) \ $(SMBD_OBJ_MAIN) $(PROCESS_MODEL_OBJ) \ $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIBSMB_OBJ) \ $(LIBRAW_OBJ) $(LIBDFS_OBJ) $(LIBCLIUTIL) $(LIBCLIAUTH_OBJ) \ - $(SMBW_OBJ1) $(SMBWRAPPER_OBJ1) $(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \ - $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) $(RPC_CLIENT_OBJ) \ + $(SMBW_OBJ1) $(SMBWRAPPER_OBJ1) $(SMBTORTURE_OBJ1) \ $(RPC_PIPE_OBJ) $(RPC_PARSE_OBJ) $(KRBCLIENT_OBJ) \ $(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \ $(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \ @@ -559,7 +550,7 @@ WINBINDD_OBJ1 = \ WINBINDD_OBJ = \ $(WINBINDD_OBJ1) $(PASSDB_GET_SET_OBJ) \ $(PARAM_OBJ) $(LIB_OBJ) \ - $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \ + $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \ $(PROFILE_OBJ) $(UNIGRP_OBJ) \ $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) @@ -717,10 +708,6 @@ bin/swat@EXEEXT@: $(SWAT_OBJ) bin/.dummy @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \ $(AUTHLIBS) $(LIBS) -bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy - @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @BUILD_POPT@ - bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @BUILD_POPT@ @@ -963,9 +950,6 @@ bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ) @echo "Linking shared library $@" $(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_PICOOBJ) -lpam $(DYNEXP) $(LIBS) -lc -bin/libmsrpc.a: $(LIBMSRPC_PICOBJ) - -$(AR) -rc $@ $(LIBMSRPC_PICOBJ) - bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(TDBBACKUP_OBJ) @@ -1014,7 +998,7 @@ installclientlib: # Python extensions PYTHON_OBJS = $(LIB_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \ - $(PARAM_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ + $(PARAM_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(SECRETS_OBJ) $(KRBCLIENT_OBJ) python_ext: $(PYTHON_OBJS) diff --git a/source4/include/context.h b/source4/include/context.h index dfb6ed1b8c..959793ab5e 100644 --- a/source4/include/context.h +++ b/source4/include/context.h @@ -331,6 +331,8 @@ struct server_context { struct timers_context timers; + struct dcesrv_context dcesrv; + /* the pid of the process handling this session */ pid_t pid; diff --git a/source4/include/includes.h b/source4/include/includes.h index fe6fcf5bce..9683d032cc 100644 --- a/source4/include/includes.h +++ b/source4/include/includes.h @@ -773,28 +773,6 @@ extern int errno; #include "librpc/ndr/libndr.h" #include "librpc/rpc/dcerpc.h" -/* - * Type for wide character dirent structure. - * Only d_name is defined by POSIX. - */ - -typedef struct smb_wdirent { - wpstring d_name; -} SMB_STRUCT_WDIRENT; - -/* - * Type for wide character passwd structure. - */ - -typedef struct smb_wpasswd { - wfstring pw_name; - char *pw_passwd; - uid_t pw_uid; - gid_t pw_gid; - wpstring pw_gecos; - wpstring pw_dir; - wpstring pw_shell; -} SMB_STRUCT_WPASSWD; /* used in net.c */ struct functable { @@ -803,20 +781,8 @@ struct functable { }; -/* Defines for wisXXX functions. */ -#define UNI_UPPER 0x1 -#define UNI_LOWER 0x2 -#define UNI_DIGIT 0x4 -#define UNI_XDIGIT 0x8 -#define UNI_SPACE 0x10 - #include "nsswitch/nss.h" -/* forward declaration from printing.h to get around - header file dependencies */ - -struct printjob; - /***** automatically generated prototypes *****/ #include "proto.h" @@ -832,23 +798,6 @@ struct printjob; #define QSORT_CAST (int (*)(const void *, const void *)) #endif -#ifndef DEFAULT_PRINTING -#ifdef HAVE_CUPS -#define DEFAULT_PRINTING PRINT_CUPS -#define PRINTCAP_NAME "cups" -#elif defined(SYSV) -#define DEFAULT_PRINTING PRINT_SYSV -#define PRINTCAP_NAME "lpstat" -#else -#define DEFAULT_PRINTING PRINT_BSD -#define PRINTCAP_NAME "/etc/printcap" -#endif -#endif - -#ifndef PRINTCAP_NAME -#define PRINTCAP_NAME "/etc/printcap" -#endif - #ifndef SIGCLD #define SIGCLD SIGCHLD #endif diff --git a/source4/include/smb.h b/source4/include/smb.h index a58556a306..a0a190190b 100644 --- a/source4/include/smb.h +++ b/source4/include/smb.h @@ -421,6 +421,7 @@ struct vuid_cache { #include "smb_acls.h" #include "enums.h" #include "events.h" +#include "rpc_server/dcerpc_server.h" #include "context.h" #include "smb_interfaces.h" #include "ntvfs.h" diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index 9acae00249..8a7a5ca68d 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -309,7 +309,7 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p, union smb_open io; TALLOC_CTX *mem_ctx; - asprintf(&name, "\\%s", pipe_name); + asprintf(&name, "\\pipe\\%s", pipe_name); if (!name) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 7ada031bd5..7ad02bb8cb 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -25,16 +25,102 @@ #include "includes.h" +/* this is the private structure used to keep the state of an open + ipc$ connection. It needs to keep information about all open + pipes */ +struct ipc_private { + + uint16 next_fnum; + uint16 num_open; + + /* a list of open pipes */ + struct pipe_state { + struct pipe_state *next, *prev; + TALLOC_CTX *mem_ctx; + const char *pipe_name; + uint16 fnum; + struct dcesrv_state *pipe_state; + } *pipe_list; + +}; + + +/* + find the next fnum available on this connection +*/ +static uint16 find_next_fnum(struct ipc_private *ipc) +{ + struct pipe_state *p; + uint32 ret; + + if (ipc->num_open == 0xFFFF) { + return 0; + } + +again: + ret = ipc->next_fnum++; + + for (p=ipc->pipe_list; p; p=p->next) { + if (p->fnum == ret) { + goto again; + } + } + + return ret; +} + + +/* + shutdown a single pipe. Called on a close or disconnect +*/ +static void pipe_shutdown(struct ipc_private *private, struct pipe_state *p) +{ + TALLOC_CTX *mem_ctx = private->pipe_list->mem_ctx; + dcesrv_endpoint_disconnect(private->pipe_list->pipe_state); + DLIST_REMOVE(private->pipe_list, private->pipe_list); + talloc_destroy(mem_ctx); +} + + +/* + find a open pipe give a file descriptor +*/ +static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16 fnum) +{ + struct pipe_state *p; + + for (p=private->pipe_list; p; p=p->next) { + if (p->fnum == fnum) { + return p; + } + } + + return NULL; +} + + /* connect to a share - always works */ static NTSTATUS ipc_connect(struct request_context *req, const char *sharename) { struct tcon_context *conn = req->conn; + struct ipc_private *private; conn->fs_type = talloc_strdup(conn->mem_ctx, "IPC"); conn->dev_type = talloc_strdup(conn->mem_ctx, "IPC"); + /* prepare the private state for this connection */ + private = talloc(conn->mem_ctx, sizeof(struct ipc_private)); + if (!private) { + return NT_STATUS_NO_MEMORY; + } + conn->ntvfs_private = (void *)private; + + private->pipe_list = NULL; + private->next_fnum = 1; + private->num_open = 0; + return NT_STATUS_OK; } @@ -43,6 +129,13 @@ static NTSTATUS ipc_connect(struct request_context *req, const char *sharename) */ static NTSTATUS ipc_disconnect(struct tcon_context *tcon) { + struct ipc_private *private = tcon->ntvfs_private; + + /* close any pipes that are open. Discard any unread data */ + while (private->pipe_list) { + pipe_shutdown(private, private->pipe_list); + } + return NT_STATUS_OK; } @@ -88,11 +181,79 @@ static NTSTATUS ipc_setpathinfo(struct request_context *req, union smb_setfilein } /* - open a file + open a file - used for MSRPC pipes */ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) { - return NT_STATUS_ACCESS_DENIED; + struct pipe_state *p; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + struct dcesrv_endpoint endpoint; + struct ipc_private *private = req->conn->ntvfs_private; + + /* for now only handle NTcreateX style opens */ + if (oi->generic.level != RAW_OPEN_NTCREATEX) { + return NT_STATUS_ACCESS_DENIED; + } + + mem_ctx = talloc_init("ipc_open '%s'", oi->ntcreatex.in.fname); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + p = talloc(mem_ctx, sizeof(struct pipe_state)); + if (!p) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + p->mem_ctx = mem_ctx; + + p->pipe_name = talloc_strdup(mem_ctx, oi->ntcreatex.in.fname); + if (!p->pipe_name) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + p->fnum = find_next_fnum(private); + if (p->fnum == 0) { + talloc_destroy(mem_ctx); + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + + if (strncasecmp(p->pipe_name, "\\pipe\\", 6) != 0) { + talloc_destroy(mem_ctx); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + p->pipe_name += 6; + + /* + we're all set, now ask the dcerpc server subsystem to open the + endpoint. At this stage the pipe isn't bound, so we don't + know what interface the user actually wants, just that they want + one of the interfaces attached to this pipe endpoint. + + TODO: note that we aren't passing any credentials here. We + will need to do that once the credentials infrastructure is + finalised for Samba4 + */ + + endpoint.type = ENDPOINT_SMB; + endpoint.info.smb_pipe = p->pipe_name; + + status = dcesrv_endpoint_connect(req->smb, &endpoint, &p->pipe_state); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; + } + + private->num_open++; + + DLIST_ADD(private->pipe_list, p); + + ZERO_STRUCT(oi->ntcreatex.out); + oi->ntcreatex.out.fnum = p->fnum; + + return NT_STATUS_OK; } /* @@ -164,7 +325,22 @@ static NTSTATUS ipc_flush(struct request_context *req, struct smb_flush *io) */ static NTSTATUS ipc_close(struct request_context *req, union smb_close *io) { - return NT_STATUS_ACCESS_DENIED; + struct ipc_private *private = req->conn->ntvfs_private; + struct pipe_state *p; + + if (io->generic.level != RAW_CLOSE_CLOSE) { + return NT_STATUS_ACCESS_DENIED; + } + + p = pipe_state_find(private, io->close.in.fnum); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } + + pipe_shutdown(private, p); + private->num_open--; + + return NT_STATUS_OK; } /* diff --git a/source4/smbd/process.c b/source4/smbd/process.c index 3b2d1cf633..db145d0a26 100644 --- a/source4/smbd/process.c +++ b/source4/smbd/process.c @@ -762,6 +762,9 @@ void init_smbsession(struct event_context *ev, struct model_ops *model_ops, int fde.flags = EVENT_FD_READ; event_add_fd(ev, &fde); + + /* setup the DCERPC server subsystem */ + dcesrv_init(smb); } -- cgit