diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-11-27 00:24:36 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:06:11 -0500 |
commit | 6895228b5c911a0859274dc7e3d427dd9cadeeca (patch) | |
tree | 92c6d399d1e19c96e09c4419decedfd142528954 /source4/ntvfs/common | |
parent | e1d7b15868888d0d34936ebb734d79cb2b9a1076 (diff) | |
download | samba-6895228b5c911a0859274dc7e3d427dd9cadeeca.tar.gz samba-6895228b5c911a0859274dc7e3d427dd9cadeeca.tar.bz2 samba-6895228b5c911a0859274dc7e3d427dd9cadeeca.zip |
r3982: split out the sid -> uid/gid mapping routines into a ntvfs_sidmap
subsystem. This is in preparation for adding better default ACL
generation in pvfs, which will require uid/gid -> sid mapping.
(This used to be commit b31108e49247495d98cf7c12ee303b12a9e44e92)
Diffstat (limited to 'source4/ntvfs/common')
-rw-r--r-- | source4/ntvfs/common/sidmap.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c new file mode 100644 index 0000000000..ac3aaaecaf --- /dev/null +++ b/source4/ntvfs/common/sidmap.c @@ -0,0 +1,212 @@ +/* + Unix SMB/CIFS implementation. + + mapping routines for SID <-> unix uid/gid + + Copyright (C) Andrew Tridgell 2004 + + 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" + +/* + private context for sid mapping routines +*/ +struct sidmap_context { + void *samctx; +}; + +/* + open a sidmap context - use talloc_free to close +*/ +struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx) +{ + struct sidmap_context *sidmap; + sidmap = talloc_p(mem_ctx, struct sidmap_context); + if (sidmap == NULL) { + return NULL; + } + sidmap->samctx = samdb_connect(sidmap); + if (sidmap->samctx == NULL) { + talloc_free(sidmap); + return NULL; + } + + return sidmap; +} + +/* + map a sid to a unix uid +*/ +NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, + struct dom_sid *sid, uid_t *uid) +{ + const char *attrs[] = { "sAMAccountName", "unixID", + "unixName", "sAMAccountType", NULL }; + int ret; + const char *s; + void *ctx; + struct ldb_message **res; + const char *sidstr; + uint_t atype; + + ctx = talloc(sidmap, 0); + sidstr = dom_sid_string(ctx, sid); + if (sidstr == NULL) { + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + + ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + "objectSid=%s", sidstr); + if (ret != 1) { + DEBUG(0,("sid_to_unixuid: unable to find sam record for sid %s\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* make sure its a user, not a group */ + atype = samdb_result_uint(res[0], "sAMAccountType", 0); + if (atype && (!(atype & ATYPE_ACCOUNT))) { + DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* first try to get the uid directly */ + s = samdb_result_string(res[0], "unixID", NULL); + if (s != NULL) { + *uid = strtoul(s, NULL, 0); + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* next try via the UnixName attribute */ + s = samdb_result_string(res[0], "unixName", NULL); + if (s != NULL) { + struct passwd *pwd = getpwnam(s); + if (!pwd) { + DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *uid = pwd->pw_uid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* finally try via the sAMAccountName attribute */ + s = samdb_result_string(res[0], "sAMAccountName", NULL); + if (s != NULL) { + struct passwd *pwd = getpwnam(s); + if (!pwd) { + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *uid = pwd->pw_uid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", sidstr)); + + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; +} + + +/* + map a sid to a unix gid +*/ +NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, + struct dom_sid *sid, gid_t *gid) +{ + const char *attrs[] = { "sAMAccountName", "unixID", + "unixName", "sAMAccountType", NULL }; + int ret; + const char *s; + void *ctx; + struct ldb_message **res; + const char *sidstr; + uint_t atype; + + ctx = talloc(sidmap, 0); + sidstr = dom_sid_string(ctx, sid); + if (sidstr == NULL) { + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + + ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + "objectSid=%s", sidstr); + if (ret != 1) { + DEBUG(0,("sid_to_unixgid: unable to find sam record for sid %s\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* make sure its not a user */ + atype = samdb_result_uint(res[0], "sAMAccountType", 0); + if (atype && atype == ATYPE_NORMAL_ACCOUNT) { + DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* first try to get the gid directly */ + s = samdb_result_string(res[0], "unixID", NULL); + if (s != NULL) { + *gid = strtoul(s, NULL, 0); + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* next try via the UnixName attribute */ + s = samdb_result_string(res[0], "unixName", NULL); + if (s != NULL) { + struct group *grp = getgrnam(s); + if (!grp) { + DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", + s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *gid = grp->gr_gid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* finally try via the sAMAccountName attribute */ + s = samdb_result_string(res[0], "sAMAccountName", NULL); + if (s != NULL) { + struct group *grp = getgrnam(s); + if (!grp) { + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *gid = grp->gr_gid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + DEBUG(0,("sid_to_unixgid: no unixID, unixName or sAMAccountName for sid %s\n", + sidstr)); + + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; +} |