diff options
-rw-r--r-- | source4/librpc/config.mk | 15 | ||||
-rw-r--r-- | source4/librpc/idl/unixinfo.idl | 56 | ||||
-rw-r--r-- | source4/rpc_server/config.mk | 13 | ||||
-rw-r--r-- | source4/rpc_server/unixinfo/dcesrv_unixinfo.c | 174 | ||||
-rw-r--r-- | source4/torture/config.mk | 3 | ||||
-rw-r--r-- | source4/torture/rpc/unixinfo.c | 91 | ||||
-rw-r--r-- | source4/torture/torture.c | 1 |
7 files changed, 350 insertions, 3 deletions
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 0ee9c0f501..45cc360f24 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -113,6 +113,12 @@ INIT_OBJ_FILES = librpc/gen_ndr/ndr_policyagent.o NOPROTO = YES REQUIRED_SUBSYSTEMS = NDR +[SUBSYSTEM::NDR_UNIXINFO] +INIT_FUNCTION = dcerpc_unixinfo_init +INIT_OBJ_FILES = librpc/gen_ndr/ndr_unixinfo.o +NOPROTO = YES +REQUIRED_SUBSYSTEMS = NDR + [SUBSYSTEM::NDR_SAMR] INIT_FUNCTION = dcerpc_samr_init INIT_OBJ_FILES = librpc/gen_ndr/ndr_samr.o @@ -321,7 +327,7 @@ REQUIRED_SUBSYSTEMS = NDR NDR_NBT [SUBSYSTEM::NDR_ALL] REQUIRED_SUBSYSTEMS = NDR_AUDIOSRV NDR_ECHO NDR_DCERPC NDR_EXCHANGE \ NDR_DSBACKUP NDR_EFS NDR_MISC NDR_LSA NDR_DFS NDR_DRSUAPI \ - NDR_POLICYAGENT NDR_SAMR NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \ + NDR_POLICYAGENT NDR_UNIXINFO NDR_SAMR NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \ NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \ NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \ NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \ @@ -384,6 +390,11 @@ ADD_OBJ_FILES = librpc/gen_ndr/ndr_policyagent_c.o REQUIRED_SUBSYSTEMS = RPC NDR_POLICYAGENT NOPROTO = YES +[SUBSYSTEM::RPC_NDR_UNIXINFO] +ADD_OBJ_FILES = librpc/gen_ndr/ndr_unixinfo_c.o +REQUIRED_SUBSYSTEMS = RPC NDR_UNIXINFO +NOPROTO = YES + [SUBSYSTEM::RPC_NDR_SAMR] ADD_OBJ_FILES = librpc/gen_ndr/ndr_samr_c.o REQUIRED_SUBSYSTEMS = RPC NDR_SAMR @@ -522,6 +533,6 @@ NOPROTO = YES ################################################ # Start SUBSYSTEM RPC [SUBSYSTEM::RPC] -REQUIRED_SUBSYSTEMS = NDR_RAW RPC_RAW LIBSMB NDR_MISC NDR_DCERPC NDR_SCHANNEL NDR_LSA NDR_NETLOGON NDR_SAMR RPC_NDR_NETLOGON RPC_NDR_EPMAPPER +REQUIRED_SUBSYSTEMS = NDR_RAW RPC_RAW LIBSMB NDR_MISC NDR_DCERPC NDR_SCHANNEL NDR_LSA NDR_NETLOGON NDR_SAMR NDR_UNIXINFO RPC_NDR_NETLOGON RPC_NDR_EPMAPPER # End SUBSYSTEM RPC ################################################ diff --git a/source4/librpc/idl/unixinfo.idl b/source4/librpc/idl/unixinfo.idl new file mode 100644 index 0000000000..e740368875 --- /dev/null +++ b/source4/librpc/idl/unixinfo.idl @@ -0,0 +1,56 @@ +#include "idl_types.h" + +/* + Unixinfo interface definition +*/ + +[ uuid("9c54e310-a955-4885-bd31-78787147dfa6"), + version(0.0), + endpoint("ncacn_np:[\\pipe\\unixinfo]", "ncacn_ip_tcp:", "ncalrpc:"), + pointer_default(unique), + helpstring("Unixinfo specific stuff"), + depends(security) +] interface unixinfo +{ + /******************/ + /* Function: 0x00 */ + NTSTATUS unixinfo_SidToUid ( + [in] dom_sid sid, + [out] hyper uid + ); + + /******************/ + /* Function: 0x01 */ + NTSTATUS unixinfo_UidToSid ( + [in] hyper uid, + [out] dom_sid *sid + ); + + /******************/ + /* Function: 0x02 */ + NTSTATUS unixinfo_SidToGid ( + [in] dom_sid sid, + [out] hyper gid + ); + + /******************/ + /* Function: 0x03 */ + NTSTATUS unixinfo_GidToSid ( + [in] hyper gid, + [out] dom_sid *sid + ); + + typedef struct { + NTSTATUS status; + utf8string homedir; + utf8string shell; + } unixinfo_GetPWUidInfo; + + /******************/ + /* Function: 0x04 */ + NTSTATUS unixinfo_GetPWUid ( + [in,out,range(0,1023)] uint32 count, + [in,size_is(count)] hyper uids[], + [out,size_is(count)] unixinfo_GetPWUidInfo infos[] + ); +} diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index 74483c9362..ce30a404e6 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -87,6 +87,19 @@ REQUIRED_SUBSYSTEMS = \ ################################################ ################################################ +# Start MODULE dcerpc_unixinfo +[MODULE::dcerpc_unixinfo] +INIT_FUNCTION = dcerpc_server_unixinfo_init +SUBSYSTEM = DCERPC +INIT_OBJ_FILES = \ + rpc_server/unixinfo/dcesrv_unixinfo.o +REQUIRED_SUBSYSTEMS = \ + DCERPC_COMMON \ + NDR_UNIXINFO +# End MODULE dcerpc_unixinfo +################################################ + +################################################ # Start MODULE dcerpc_samr [MODULE::dcerpc_samr] INIT_FUNCTION = dcerpc_server_samr_init diff --git a/source4/rpc_server/unixinfo/dcesrv_unixinfo.c b/source4/rpc_server/unixinfo/dcesrv_unixinfo.c new file mode 100644 index 0000000000..b85d3f144e --- /dev/null +++ b/source4/rpc_server/unixinfo/dcesrv_unixinfo.c @@ -0,0 +1,174 @@ +/* + Unix SMB/CIFS implementation. + + endpoint server for the unixinfo pipe + + Copyright (C) Volker Lendecke 2005 + + 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" +#include "rpc_server/dcerpc_server.h" +#include "rpc_server/common/common.h" +#include "librpc/gen_ndr/ndr_unixinfo.h" +#include "lib/events/events.h" + +#include <sys/types.h> +#include <pwd.h> + +static NTSTATUS unixinfo_SidToUid(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct unixinfo_SidToUid *r) +{ + struct sidmap_context *sidmap; + uid_t uid; + + sidmap = sidmap_open(mem_ctx); + if (sidmap == NULL) { + DEBUG(10, ("sidmap_open failed\n")); + return NT_STATUS_NO_MEMORY; + } + + r->out.result = sidmap_sid_to_unixuid(sidmap, &r->in.sid, &uid); + + if (NT_STATUS_IS_OK(r->out.result)) { + r->out.uid = uid; + } + + return r->out.result; +} + +static NTSTATUS unixinfo_UidToSid(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct unixinfo_UidToSid *r) +{ + struct sidmap_context *sidmap; + uid_t uid; + + sidmap = sidmap_open(mem_ctx); + if (sidmap == NULL) { + DEBUG(10, ("sidmap_open failed\n")); + return NT_STATUS_NO_MEMORY; + } + + uid = r->in.uid; /* This cuts uid to (probably) 32 bit */ + + if ((uint64_t)uid != r->in.uid) { + DEBUG(10, ("uid out of range\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + r->out.sid = NULL; + r->out.result = sidmap_uid_to_sid(sidmap, mem_ctx, uid, &r->out.sid); + return r->out.result; +} + +static NTSTATUS unixinfo_SidToGid(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct unixinfo_SidToGid *r) +{ + struct sidmap_context *sidmap; + gid_t gid; + + sidmap = sidmap_open(mem_ctx); + if (sidmap == NULL) { + DEBUG(10, ("sidmap_open failed\n")); + return NT_STATUS_NO_MEMORY; + } + + r->out.result = sidmap_sid_to_unixgid(sidmap, &r->in.sid, &gid); + + if (NT_STATUS_IS_OK(r->out.result)) { + r->out.gid = gid; + } + + return r->out.result; +} + +static NTSTATUS unixinfo_GidToSid(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct unixinfo_GidToSid *r) +{ + struct sidmap_context *sidmap; + gid_t gid; + + sidmap = sidmap_open(mem_ctx); + if (sidmap == NULL) { + DEBUG(10, ("sidmap_open failed\n")); + return NT_STATUS_NO_MEMORY; + } + + gid = r->in.gid; /* This cuts gid to (probably) 32 bit */ + + if ((uint64_t)gid != r->in.gid) { + DEBUG(10, ("gid out of range\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + r->out.sid = NULL; + r->out.result = sidmap_gid_to_sid(sidmap, mem_ctx, gid, &r->out.sid); + return r->out.result; +} + +static NTSTATUS unixinfo_GetPWUid(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct unixinfo_GetPWUid *r) +{ + int i; + + r->out.infos = talloc_zero_array(mem_ctx, struct unixinfo_GetPWUidInfo, + r->in.count); + if (r->out.infos == NULL) { + DEBUG(0, ("talloc failed\n")); + return NT_STATUS_NO_MEMORY; + } + + r->out.result = NT_STATUS_OK; + r->out.count = r->in.count; + + for (i=0; i<r->in.count; i++) { + uid_t uid; + struct passwd *pwd; + + uid = r->in.uids[i]; + pwd = getpwuid(uid); + if (pwd == NULL) { + DEBUG(10, ("uid %d not found\n", uid)); + r->out.infos[i].homedir = ""; + r->out.infos[i].shell = ""; + r->out.infos[i].status = NT_STATUS_NO_SUCH_USER; + continue; + } + + r->out.infos[i].homedir = talloc_strdup(mem_ctx, pwd->pw_dir); + r->out.infos[i].shell = talloc_strdup(mem_ctx, pwd->pw_shell); + + if ((r->out.infos[i].homedir == NULL) || + (r->out.infos[i].shell == NULL)) { + r->out.infos[i].homedir = ""; + r->out.infos[i].shell = ""; + r->out.infos[i].status = NT_STATUS_NO_MEMORY; + continue; + } + + r->out.infos[i].status = NT_STATUS_OK; + } + + return NT_STATUS_OK; +} + +/* include the generated boilerplate */ +#include "librpc/gen_ndr/ndr_unixinfo_s.c" diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 71f500bba4..2749318080 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -77,6 +77,7 @@ ADD_OBJ_FILES = \ torture/rpc/dfs.o \ torture/rpc/drsuapi.o \ torture/rpc/spoolss.o \ + torture/rpc/unixinfo.o \ torture/rpc/samr.o \ torture/rpc/wkssvc.o \ torture/rpc/srvsvc.o \ @@ -104,7 +105,7 @@ ADD_OBJ_FILES = \ torture/rpc/alter_context.o \ torture/rpc/bench.o REQUIRED_SUBSYSTEMS = \ - NDR_ALL RPC_NDR_SAMR RPC_NDR_WINREG RPC_NDR_INITSHUTDOWN \ + NDR_ALL RPC_NDR_UNIXINFO RPC_NDR_SAMR RPC_NDR_WINREG RPC_NDR_INITSHUTDOWN \ RPC_NDR_OXIDRESOLVER RPC_NDR_EVENTLOG RPC_NDR_ECHO RPC_NDR_SVCCTL \ RPC_NDR_MGMT RPC_NDR_NETLOGON RPC_NDR_ATSVC RPC_NDR_DRSUAPI \ RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_SPOOLSS \ diff --git a/source4/torture/rpc/unixinfo.c b/source4/torture/rpc/unixinfo.c new file mode 100644 index 0000000000..caa268b0c8 --- /dev/null +++ b/source4/torture/rpc/unixinfo.c @@ -0,0 +1,91 @@ +/* + Unix SMB/CIFS implementation. + test suite for unixinfo rpc operations + + Copyright (C) Volker Lendecke 2005 + + 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" +#include "lib/events/events.h" +#include "librpc/gen_ndr/ndr_unixinfo.h" + + +/* + test the UidToSid interface +*/ +static BOOL test_uidtosid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + struct unixinfo_UidToSid r; + + r.in.uid = 1000; + + status = dcerpc_unixinfo_UidToSid(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + printf("UidToSid failed == %s\n", nt_errstr(status)); + return False; + } + + return True; +} + +static BOOL test_getpwuid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) +{ + uint64_t uids[512]; + const int num_uids = sizeof(uids)/sizeof(uids[0]); + int i; + struct unixinfo_GetPWUid r; + NTSTATUS result; + + for (i=0; i<num_uids; i++) { + uids[i] = i; + } + + r.in.count = num_uids; + r.in.uids = uids; + + result = dcerpc_unixinfo_GetPWUid(p, mem_ctx, &r); + + return NT_STATUS_IS_OK(result); +} + +BOOL torture_rpc_unixinfo(void) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + TALLOC_CTX *mem_ctx; + BOOL ret = True; + + mem_ctx = talloc_init("torture_rpc_unixinfo"); + + status = torture_rpc_connection(mem_ctx, &p, + DCERPC_UNIXINFO_NAME, + DCERPC_UNIXINFO_UUID, + DCERPC_UNIXINFO_VERSION); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + ret &= test_uidtosid(p, mem_ctx); + ret &= test_getpwuid(p, mem_ctx); + + printf("\n"); + + talloc_free(mem_ctx); + + return ret; +} diff --git a/source4/torture/torture.c b/source4/torture/torture.c index 8f49a125c5..f5e52c5358 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -2260,6 +2260,7 @@ static struct { {"RPC-DFS", torture_rpc_dfs, 0}, {"RPC-SPOOLSS", torture_rpc_spoolss, 0}, {"RPC-SAMR", torture_rpc_samr, 0}, + {"RPC-UNIXINFO", torture_rpc_unixinfo, 0}, {"RPC-NETLOGON", torture_rpc_netlogon, 0}, {"RPC-SAMLOGON", torture_rpc_samlogon, 0}, {"RPC-SAMSYNC", torture_rpc_samsync, 0}, |