root/source3/winbindd/idmap_util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. idmap_uid_to_sid
  2. idmap_gid_to_sid
  3. idmap_sid_to_uid
  4. idmap_sid_to_gid

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    ID Mapping
   4    Copyright (C) Simo Sorce 2003
   5    Copyright (C) Jeremy Allison 2006
   6 
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11 
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16 
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
  19 
  20 #include "includes.h"
  21 #include "winbindd.h"
  22 #include "winbindd_proto.h"
  23 
  24 #undef DBGC_CLASS
  25 #define DBGC_CLASS DBGC_IDMAP
  26 
  27 /*****************************************************************
  28  Returns the SID mapped to the given UID.
  29  If mapping is not possible returns an error.
  30 *****************************************************************/  
  31 
  32 NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
     /* [<][>][^][v][top][bottom][index][help] */
  33 {
  34         NTSTATUS ret;
  35         struct id_map map;
  36         bool expired;
  37 
  38         DEBUG(10,("idmap_uid_to_sid: uid = [%lu], domain = '%s'\n",
  39                   (unsigned long)uid, domname?domname:"NULL"));
  40 
  41         if (winbindd_use_idmap_cache()
  42             && idmap_cache_find_uid2sid(uid, sid, &expired)) {
  43                 DEBUG(10, ("idmap_cache_find_uid2sid found %u%s\n",
  44                         (unsigned int)uid,
  45                            expired ? " (expired)": ""));
  46                 if (expired && idmap_is_online()) {
  47                         DEBUG(10, ("revalidating expired entry\n"));
  48                         goto backend;
  49                 }
  50                 if (is_null_sid(sid)) {
  51                         DEBUG(10, ("Returning negative cache entry\n"));
  52                         return NT_STATUS_NONE_MAPPED;
  53                 }
  54                 DEBUG(10, ("Returning positive cache entry\n"));
  55                 return NT_STATUS_OK;
  56         }
  57 
  58 backend:
  59         map.sid = sid;
  60         map.xid.type = ID_TYPE_UID;
  61         map.xid.id = uid;
  62 
  63         ret = idmap_backends_unixid_to_sid(domname, &map);
  64         if ( ! NT_STATUS_IS_OK(ret)) {
  65                 DEBUG(10, ("error mapping uid [%lu]\n", (unsigned long)uid));
  66                 return ret;
  67         }
  68 
  69         if (map.status != ID_MAPPED) {
  70                 if (winbindd_use_idmap_cache()) {
  71                         struct dom_sid null_sid;
  72                         ZERO_STRUCT(null_sid);
  73                         idmap_cache_set_sid2uid(&null_sid, uid);
  74                 }
  75                 DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid));
  76                 return NT_STATUS_NONE_MAPPED;
  77         }
  78 
  79         if (winbindd_use_idmap_cache()) {
  80                 idmap_cache_set_sid2uid(sid, uid);
  81         }
  82 
  83         return NT_STATUS_OK;
  84 }
  85 
  86 /*****************************************************************
  87  Returns SID mapped to the given GID.
  88  If mapping is not possible returns an error.
  89 *****************************************************************/  
  90 
  91 NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
     /* [<][>][^][v][top][bottom][index][help] */
  92 {
  93         NTSTATUS ret;
  94         struct id_map map;
  95         bool expired;
  96 
  97         DEBUG(10,("idmap_gid_to_si: gid = [%lu], domain = '%s'\n",
  98                   (unsigned long)gid, domname?domname:"NULL"));
  99 
 100         if (winbindd_use_idmap_cache()
 101             && idmap_cache_find_gid2sid(gid, sid, &expired)) {
 102                 DEBUG(10, ("idmap_cache_find_gid2sid found %u%s\n",
 103                         (unsigned int)gid,
 104                            expired ? " (expired)": ""));
 105                 if (expired && idmap_is_online()) {
 106                         DEBUG(10, ("revalidating expired entry\n"));
 107                         goto backend;
 108                 }
 109                 if (is_null_sid(sid)) {
 110                         DEBUG(10, ("Returning negative cache entry\n"));
 111                         return NT_STATUS_NONE_MAPPED;
 112                 }
 113                 DEBUG(10, ("Returning positive cache entry\n"));
 114                 return NT_STATUS_OK;
 115         }
 116 
 117 backend:
 118         map.sid = sid;
 119         map.xid.type = ID_TYPE_GID;
 120         map.xid.id = gid;
 121 
 122         ret = idmap_backends_unixid_to_sid(domname, &map);
 123         if ( ! NT_STATUS_IS_OK(ret)) {
 124                 DEBUG(10, ("error mapping gid [%lu]\n", (unsigned long)gid));
 125                 return ret;
 126         }
 127 
 128         if (map.status != ID_MAPPED) {
 129                 if (winbindd_use_idmap_cache()) {
 130                         struct dom_sid null_sid;
 131                         ZERO_STRUCT(null_sid);
 132                         idmap_cache_set_sid2uid(&null_sid, gid);
 133                 }
 134                 DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid));
 135                 return NT_STATUS_NONE_MAPPED;
 136         }
 137 
 138         if (winbindd_use_idmap_cache()) {
 139                 idmap_cache_set_sid2gid(sid, gid);
 140         }
 141 
 142         return NT_STATUS_OK;
 143 }
 144 
 145 /*****************************************************************
 146  Returns the UID mapped to the given SID.
 147  If mapping is not possible or SID maps to a GID returns an error.
 148 *****************************************************************/  
 149 
 150 NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
     /* [<][>][^][v][top][bottom][index][help] */
 151 {
 152         NTSTATUS ret;
 153         struct id_map map;
 154         bool expired;
 155 
 156         DEBUG(10,("idmap_sid_to_uid: sid = [%s], domain = '%s'\n",
 157                   sid_string_dbg(sid), dom_name));
 158 
 159         if (winbindd_use_idmap_cache()
 160             && idmap_cache_find_sid2uid(sid, uid, &expired)) {
 161                 DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
 162                            (int)(*uid), expired ? " (expired)": ""));
 163                 if (expired && idmap_is_online()) {
 164                         DEBUG(10, ("revalidating expired entry\n"));
 165                         goto backend;
 166                 }
 167                 if ((*uid) == -1) {
 168                         DEBUG(10, ("Returning negative cache entry\n"));
 169                         return NT_STATUS_NONE_MAPPED;
 170                 }
 171                 DEBUG(10, ("Returning positive cache entry\n"));
 172                 return NT_STATUS_OK;
 173         }
 174 
 175 backend:
 176         map.sid = sid;
 177         map.xid.type = ID_TYPE_UID;     
 178 
 179         ret = idmap_backends_sid_to_unixid(dom_name, &map);
 180 
 181         if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
 182                 if (map.xid.type != ID_TYPE_UID) {
 183                         DEBUG(10, ("sid [%s] not mapped to a uid "
 184                                    "[%u,%u,%u]\n",
 185                                    sid_string_dbg(sid),
 186                                    map.status,
 187                                    map.xid.type,
 188                                    map.xid.id));
 189                         if (winbindd_use_idmap_cache()) {
 190                                 idmap_cache_set_sid2uid(sid, -1);
 191                         }
 192                         return NT_STATUS_NONE_MAPPED;
 193                 }
 194                 goto done;
 195         }
 196 
 197         if (dom_name[0] != '\0') {
 198                 /*
 199                  * We had the task to go to a specific domain which
 200                  * could not answer our request. Fail.
 201                  */
 202                 if (winbindd_use_idmap_cache()) {
 203                         idmap_cache_set_sid2uid(sid, -1);
 204                 }
 205                 return NT_STATUS_NONE_MAPPED;
 206         }
 207 
 208         ret = idmap_new_mapping(sid, ID_TYPE_UID, &map.xid);
 209 
 210         if (!NT_STATUS_IS_OK(ret)) {
 211                 DEBUG(10, ("idmap_new_mapping failed: %s\n",
 212                            nt_errstr(ret)));
 213                 if (winbindd_use_idmap_cache()) {
 214                         idmap_cache_set_sid2uid(sid, -1);
 215                 }
 216                 return ret;
 217         }
 218 
 219 done:
 220         *uid = (uid_t)map.xid.id;
 221         if (winbindd_use_idmap_cache()) {
 222                 idmap_cache_set_sid2uid(sid, *uid);
 223         }
 224         return NT_STATUS_OK;
 225 }
 226 
 227 /*****************************************************************
 228  Returns the GID mapped to the given SID.
 229  If mapping is not possible or SID maps to a UID returns an error.
 230 *****************************************************************/  
 231 
 232 NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
     /* [<][>][^][v][top][bottom][index][help] */
 233 {
 234         NTSTATUS ret;
 235         struct id_map map;
 236         bool expired;
 237 
 238         DEBUG(10,("idmap_sid_to_gid: sid = [%s], domain = '%s'\n",
 239                   sid_string_dbg(sid), domname));
 240 
 241         if (winbindd_use_idmap_cache()
 242             && idmap_cache_find_sid2gid(sid, gid, &expired)) {
 243                 DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
 244                            (int)(*gid), expired ? " (expired)": ""));
 245                 if (expired && idmap_is_online()) {
 246                         DEBUG(10, ("revalidating expired entry\n"));
 247                         goto backend;
 248                 }
 249                 if ((*gid) == -1) {
 250                         DEBUG(10, ("Returning negative cache entry\n"));
 251                         return NT_STATUS_NONE_MAPPED;
 252                 }
 253                 DEBUG(10, ("Returning positive cache entry\n"));
 254                 return NT_STATUS_OK;
 255         }
 256 
 257 backend:
 258         map.sid = sid;
 259         map.xid.type = ID_TYPE_GID;
 260 
 261         ret = idmap_backends_sid_to_unixid(domname, &map);
 262         if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
 263                 if (map.xid.type != ID_TYPE_GID) {
 264                         DEBUG(10, ("sid [%s] not mapped to a gid "
 265                                    "[%u,%u,%u]\n",
 266                                    sid_string_dbg(sid),
 267                                    map.status,
 268                                    map.xid.type,
 269                                    map.xid.id));
 270                         if (winbindd_use_idmap_cache()) {
 271                                 idmap_cache_set_sid2gid(sid, -1);
 272                         }
 273                         return NT_STATUS_NONE_MAPPED;
 274                 }
 275                 goto done;
 276         }
 277 
 278         if (domname[0] != '\0') {
 279                 /*
 280                  * We had the task to go to a specific domain which
 281                  * could not answer our request. Fail.
 282                  */
 283                 if (winbindd_use_idmap_cache()) {
 284                         idmap_cache_set_sid2uid(sid, -1);
 285                 }
 286                 return NT_STATUS_NONE_MAPPED;
 287         }
 288 
 289         ret = idmap_new_mapping(sid, ID_TYPE_GID, &map.xid);
 290 
 291         if (!NT_STATUS_IS_OK(ret)) {
 292                 DEBUG(10, ("idmap_new_mapping failed: %s\n",
 293                            nt_errstr(ret)));
 294                 if (winbindd_use_idmap_cache()) {
 295                         idmap_cache_set_sid2gid(sid, -1);
 296                 }
 297                 return ret;
 298         }
 299 
 300 done:
 301         *gid = map.xid.id;
 302         if (winbindd_use_idmap_cache()) {
 303                 idmap_cache_set_sid2gid(sid, *gid);
 304         }
 305         return NT_STATUS_OK;
 306 }

/* [<][>][^][v][top][bottom][index][help] */