diff options
Diffstat (limited to 'source3/rpc_server/srv_unixinfo_nt.c')
-rw-r--r-- | source3/rpc_server/srv_unixinfo_nt.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/source3/rpc_server/srv_unixinfo_nt.c b/source3/rpc_server/srv_unixinfo_nt.c new file mode 100644 index 0000000000..79756f20a7 --- /dev/null +++ b/source3/rpc_server/srv_unixinfo_nt.c @@ -0,0 +1,166 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines for 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. + */ + +/* This is the interface to the rpcunixinfo pipe. */ + +#include "includes.h" +#include "nterr.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +/* Map a sid to a uid */ + +NTSTATUS _unixinfo_sid_to_uid(pipes_struct *p, + UNIXINFO_Q_SID_TO_UID *q_u, + UNIXINFO_R_SID_TO_UID *r_u) +{ + uid_t uid; + + r_u->uid.low = 0; + r_u->uid.high = 0; + + r_u->status = sid_to_uid(&q_u->sid, &uid) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED; + if (NT_STATUS_IS_OK(r_u->status)) + r_u->uid.low = uid; + + return r_u->status; +} + +/* Map a uid to a sid */ + +NTSTATUS _unixinfo_uid_to_sid(pipes_struct *p, + UNIXINFO_Q_UID_TO_SID *q_u, + UNIXINFO_R_UID_TO_SID *r_u) +{ + DOM_SID sid; + + r_u->status = NT_STATUS_NO_SUCH_USER; + + if (q_u->uid.high == 0) { + uid_to_sid(&sid, q_u->uid.low); + r_u->status = NT_STATUS_OK; + } + + init_r_unixinfo_uid_to_sid(r_u, + NT_STATUS_IS_OK(r_u->status) ? &sid : NULL); + + return r_u->status; +} + +/* Map a sid to a gid */ + +NTSTATUS _unixinfo_sid_to_gid(pipes_struct *p, + UNIXINFO_Q_SID_TO_GID *q_u, + UNIXINFO_R_SID_TO_GID *r_u) +{ + gid_t gid; + + r_u->gid.low = 0; + r_u->gid.high = 0; + + r_u->status = sid_to_gid(&q_u->sid, &gid) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED; + if (NT_STATUS_IS_OK(r_u->status)) + r_u->gid.low = gid; + + return r_u->status; +} + +/* Map a gid to a sid */ + +NTSTATUS _unixinfo_gid_to_sid(pipes_struct *p, + UNIXINFO_Q_GID_TO_SID *q_u, + UNIXINFO_R_GID_TO_SID *r_u) +{ + DOM_SID sid; + + r_u->status = NT_STATUS_NO_SUCH_USER; + + if (q_u->gid.high == 0) { + gid_to_sid(&sid, q_u->gid.low); + r_u->status = NT_STATUS_OK; + } + + init_r_unixinfo_gid_to_sid(r_u, + NT_STATUS_IS_OK(r_u->status) ? &sid : NULL); + + return r_u->status; +} + +/* Get unix struct passwd information */ + +NTSTATUS _unixinfo_getpwuid(pipes_struct *p, + UNIXINFO_Q_GETPWUID *q_u, + UNIXINFO_R_GETPWUID *r_u) +{ + int i; + + if (r_u->count > 1023) { + return NT_STATUS_INVALID_PARAMETER; + } + + r_u->info = TALLOC_ARRAY(p->mem_ctx, struct unixinfo_getpwuid, + q_u->count); + + if ((r_u->count > 0) && (r_u->info == NULL)) { + return NT_STATUS_NO_MEMORY; + } + + r_u->status = NT_STATUS_OK; + r_u->count = q_u->count; + + for (i=0; i<r_u->count; i++) { + struct passwd *pw; + char *homedir, *shell; + ssize_t len1, len2; + + r_u->info[i].status = NT_STATUS_NO_SUCH_USER; + r_u->info[i].homedir = ""; + r_u->info[i].shell = ""; + + if (q_u->uid[i].high != 0) { + DEBUG(10, ("64-bit uids not yet supported...\n")); + continue; + } + + pw = getpwuid(q_u->uid[i].low); + + if (pw == NULL) { + DEBUG(10, ("Did not find uid %d\n", q_u->uid[i].low)); + continue; + } + + len1 = push_utf8_talloc(p->mem_ctx, &homedir, pw->pw_dir); + len2 = push_utf8_talloc(p->mem_ctx, &shell, pw->pw_shell); + + if ((len1 < 0) || (len2 < 0) || (homedir == NULL) || + (shell == NULL)) { + DEBUG(3, ("push_utf8_talloc failed\n")); + r_u->info[i].status = NT_STATUS_NO_MEMORY; + continue; + } + + r_u->info[i].status = NT_STATUS_OK; + r_u->info[i].homedir = homedir; + r_u->info[i].shell = shell; + } + + return r_u->status; +} |