root/source3/winbindd/idmap_nss.c

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

DEFINITIONS

This source file includes following definitions.
  1. idmap_nss_int_init
  2. idmap_nss_unixids_to_sids
  3. idmap_nss_sids_to_unixids
  4. idmap_nss_close
  5. idmap_nss_init

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    idmap PASSDB backend
   5 
   6    Copyright (C) Simo Sorce 2006
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "winbindd.h"
  24 
  25 #undef DBGC_CLASS
  26 #define DBGC_CLASS DBGC_IDMAP
  27 
  28 /*****************************
  29  Initialise idmap database. 
  30 *****************************/
  31 
  32 static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom,
     /* [<][>][^][v][top][bottom][index][help] */
  33                                    const char *params)
  34 {       
  35         return NT_STATUS_OK;
  36 }
  37 
  38 /**********************************
  39  lookup a set of unix ids. 
  40 **********************************/
  41 
  42 static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         TALLOC_CTX *ctx;
  45         int i;
  46 
  47         /* initialize the status to avoid suprise */
  48         for (i = 0; ids[i]; i++) {
  49                 ids[i]->status = ID_UNKNOWN;
  50         }
  51         
  52         ctx = talloc_new(dom);
  53         if ( ! ctx) {
  54                 DEBUG(0, ("Out of memory!\n"));
  55                 return NT_STATUS_NO_MEMORY;
  56         }
  57 
  58         for (i = 0; ids[i]; i++) {
  59                 struct passwd *pw;
  60                 struct group *gr;
  61                 const char *name;
  62                 enum lsa_SidType type;
  63                 bool ret;
  64                 
  65                 switch (ids[i]->xid.type) {
  66                 case ID_TYPE_UID:
  67                         pw = getpwuid((uid_t)ids[i]->xid.id);
  68 
  69                         if (!pw) {
  70                                 ids[i]->status = ID_UNMAPPED;
  71                                 continue;
  72                         }
  73                         name = pw->pw_name;
  74                         break;
  75                 case ID_TYPE_GID:
  76                         gr = getgrgid((gid_t)ids[i]->xid.id);
  77 
  78                         if (!gr) {
  79                                 ids[i]->status = ID_UNMAPPED;
  80                                 continue;
  81                         }
  82                         name = gr->gr_name;
  83                         break;
  84                 default: /* ?? */
  85                         ids[i]->status = ID_UNKNOWN;
  86                         continue;
  87                 }
  88 
  89                 /* by default calls to winbindd are disabled
  90                    the following call will not recurse so this is safe */
  91                 (void)winbind_on();
  92                 /* Lookup name from PDC using lsa_lookup_names() */
  93                 ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type);
  94                 (void)winbind_off();
  95 
  96                 if (!ret) {
  97                         /* TODO: how do we know if the name is really not mapped,
  98                          * or something just failed ? */
  99                         ids[i]->status = ID_UNMAPPED;
 100                         continue;
 101                 }
 102 
 103                 switch (type) {
 104                 case SID_NAME_USER:
 105                         if (ids[i]->xid.type == ID_TYPE_UID) {
 106                                 ids[i]->status = ID_MAPPED;
 107                         }
 108                         break;
 109 
 110                 case SID_NAME_DOM_GRP:
 111                 case SID_NAME_ALIAS:
 112                 case SID_NAME_WKN_GRP:
 113                         if (ids[i]->xid.type == ID_TYPE_GID) {
 114                                 ids[i]->status = ID_MAPPED;
 115                         }
 116                         break;
 117 
 118                 default:
 119                         ids[i]->status = ID_UNKNOWN;
 120                         break;
 121                 }
 122         }
 123 
 124 
 125         talloc_free(ctx);
 126         return NT_STATUS_OK;
 127 }
 128 
 129 /**********************************
 130  lookup a set of sids. 
 131 **********************************/
 132 
 133 static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
     /* [<][>][^][v][top][bottom][index][help] */
 134 {
 135         TALLOC_CTX *ctx;
 136         int i;
 137 
 138         /* initialize the status to avoid suprise */
 139         for (i = 0; ids[i]; i++) {
 140                 ids[i]->status = ID_UNKNOWN;
 141         }
 142         
 143         ctx = talloc_new(dom);
 144         if ( ! ctx) {
 145                 DEBUG(0, ("Out of memory!\n"));
 146                 return NT_STATUS_NO_MEMORY;
 147         }
 148 
 149         for (i = 0; ids[i]; i++) {
 150                 struct group *gr;
 151                 enum lsa_SidType type;
 152                 const char *dom_name = NULL;
 153                 const char *name = NULL;
 154                 bool ret;
 155 
 156                 /* by default calls to winbindd are disabled
 157                    the following call will not recurse so this is safe */
 158                 (void)winbind_on();
 159                 ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type);
 160                 (void)winbind_off();
 161 
 162                 if (!ret) {
 163                         /* TODO: how do we know if the name is really not mapped,
 164                          * or something just failed ? */
 165                         ids[i]->status = ID_UNMAPPED;
 166                         continue;
 167                 }
 168 
 169                 switch (type) {
 170                 case SID_NAME_USER: {
 171                         struct passwd *pw;
 172 
 173                         /* this will find also all lower case name and use username level */
 174 
 175                         pw = Get_Pwnam_alloc(talloc_tos(), name);
 176                         if (pw) {
 177                                 ids[i]->xid.id = pw->pw_uid;
 178                                 ids[i]->xid.type = ID_TYPE_UID;
 179                                 ids[i]->status = ID_MAPPED;
 180                         }
 181                         TALLOC_FREE(pw);
 182                         break;
 183                 }
 184 
 185                 case SID_NAME_DOM_GRP:
 186                 case SID_NAME_ALIAS:
 187                 case SID_NAME_WKN_GRP:
 188 
 189                         gr = getgrnam(name);
 190                         if (gr) {
 191                                 ids[i]->xid.id = gr->gr_gid;
 192                                 ids[i]->xid.type = ID_TYPE_GID;
 193                                 ids[i]->status = ID_MAPPED;
 194                         }
 195                         break;
 196 
 197                 default:
 198                         ids[i]->status = ID_UNKNOWN;
 199                         break;
 200                 }
 201         }
 202 
 203         talloc_free(ctx);
 204         return NT_STATUS_OK;
 205 }
 206 
 207 /**********************************
 208  Close the idmap tdb instance
 209 **********************************/
 210 
 211 static NTSTATUS idmap_nss_close(struct idmap_domain *dom)
     /* [<][>][^][v][top][bottom][index][help] */
 212 {
 213         return NT_STATUS_OK;
 214 }
 215 
 216 static struct idmap_methods nss_methods = {
 217 
 218         .init = idmap_nss_int_init,
 219         .unixids_to_sids = idmap_nss_unixids_to_sids,
 220         .sids_to_unixids = idmap_nss_sids_to_unixids,
 221         .close_fn = idmap_nss_close
 222 };
 223 
 224 NTSTATUS idmap_nss_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 225 {
 226         return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "nss", &nss_methods);
 227 }

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