| 1 | /* 
 | 
|---|
| 2 |    Unix SMB/CIFS implementation.
 | 
|---|
| 3 |    Password and authentication handling
 | 
|---|
| 4 |    Copyright (C) Andrew Bartlett                        2002
 | 
|---|
| 5 |    Copyright (C) Jelmer Vernooij                        2002
 | 
|---|
| 6 |    Copyright (C) Simo Sorce                             2003
 | 
|---|
| 7 |    Copyright (C) Volker Lendecke                        2006
 | 
|---|
| 8 | 
 | 
|---|
| 9 |    This program is free software; you can redistribute it and/or modify
 | 
|---|
| 10 |    it under the terms of the GNU General Public License as published by
 | 
|---|
| 11 |    the Free Software Foundation; either version 3 of the License, or
 | 
|---|
| 12 |    (at your option) any later version.
 | 
|---|
| 13 | 
 | 
|---|
| 14 |    This program is distributed in the hope that it will be useful,
 | 
|---|
| 15 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 16 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 17 |    GNU General Public License for more details.
 | 
|---|
| 18 | 
 | 
|---|
| 19 |    You should have received a copy of the GNU General Public License
 | 
|---|
| 20 |    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
|---|
| 21 | */
 | 
|---|
| 22 | 
 | 
|---|
| 23 | #include "includes.h"
 | 
|---|
| 24 | 
 | 
|---|
| 25 | #undef DBGC_CLASS
 | 
|---|
| 26 | #define DBGC_CLASS DBGC_PASSDB
 | 
|---|
| 27 | 
 | 
|---|
| 28 | static_decl_pdb;
 | 
|---|
| 29 | 
 | 
|---|
| 30 | static struct pdb_init_function_entry *backends = NULL;
 | 
|---|
| 31 | 
 | 
|---|
| 32 | static void lazy_initialize_passdb(void)
 | 
|---|
| 33 | {
 | 
|---|
| 34 |         static bool initialized = False;
 | 
|---|
| 35 |         if(initialized) {
 | 
|---|
| 36 |                 return;
 | 
|---|
| 37 |         }
 | 
|---|
| 38 |         static_init_pdb;
 | 
|---|
| 39 |         initialized = True;
 | 
|---|
| 40 | }
 | 
|---|
| 41 | 
 | 
|---|
| 42 | static bool lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
 | 
|---|
| 43 |                                   const char **name,
 | 
|---|
| 44 |                                   enum lsa_SidType *psid_name_use,
 | 
|---|
| 45 |                                   union unid_t *unix_id);
 | 
|---|
| 46 | 
 | 
|---|
| 47 | NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init) 
 | 
|---|
| 48 | {
 | 
|---|
| 49 |         struct pdb_init_function_entry *entry = backends;
 | 
|---|
| 50 | 
 | 
|---|
| 51 |         if(version != PASSDB_INTERFACE_VERSION) {
 | 
|---|
| 52 |                 DEBUG(0,("Can't register passdb backend!\n"
 | 
|---|
| 53 |                          "You tried to register a passdb module with PASSDB_INTERFACE_VERSION %d, "
 | 
|---|
| 54 |                          "while this version of samba uses version %d\n", 
 | 
|---|
| 55 |                          version,PASSDB_INTERFACE_VERSION));
 | 
|---|
| 56 |                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
 | 
|---|
| 57 |         }
 | 
|---|
| 58 | 
 | 
|---|
| 59 |         if (!name || !init) {
 | 
|---|
| 60 |                 return NT_STATUS_INVALID_PARAMETER;
 | 
|---|
| 61 |         }
 | 
|---|
| 62 | 
 | 
|---|
| 63 |         DEBUG(5,("Attempting to register passdb backend %s\n", name));
 | 
|---|
| 64 | 
 | 
|---|
| 65 |         /* Check for duplicates */
 | 
|---|
| 66 |         if (pdb_find_backend_entry(name)) {
 | 
|---|
| 67 |                 DEBUG(0,("There already is a passdb backend registered with the name %s!\n", name));
 | 
|---|
| 68 |                 return NT_STATUS_OBJECT_NAME_COLLISION;
 | 
|---|
| 69 |         }
 | 
|---|
| 70 | 
 | 
|---|
| 71 |         entry = SMB_XMALLOC_P(struct pdb_init_function_entry);
 | 
|---|
| 72 |         entry->name = smb_xstrdup(name);
 | 
|---|
| 73 |         entry->init = init;
 | 
|---|
| 74 | 
 | 
|---|
| 75 |         DLIST_ADD(backends, entry);
 | 
|---|
| 76 |         DEBUG(5,("Successfully added passdb backend '%s'\n", name));
 | 
|---|
| 77 |         return NT_STATUS_OK;
 | 
|---|
| 78 | }
 | 
|---|
| 79 | 
 | 
|---|
| 80 | struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
 | 
|---|
| 81 | {
 | 
|---|
| 82 |         struct pdb_init_function_entry *entry = backends;
 | 
|---|
| 83 | 
 | 
|---|
| 84 |         while(entry) {
 | 
|---|
| 85 |                 if (strcmp(entry->name, name)==0) return entry;
 | 
|---|
| 86 |                 entry = entry->next;
 | 
|---|
| 87 |         }
 | 
|---|
| 88 | 
 | 
|---|
| 89 |         return NULL;
 | 
|---|
| 90 | }
 | 
|---|
| 91 | 
 | 
|---|
| 92 | /*
 | 
|---|
| 93 |  * The event context for the passdb backend. I know this is a bad hack and yet
 | 
|---|
| 94 |  * another static variable, but our pdb API is a global thing per
 | 
|---|
| 95 |  * definition. The first use for this is the LDAP idle function, more might be
 | 
|---|
| 96 |  * added later.
 | 
|---|
| 97 |  *
 | 
|---|
| 98 |  * I don't feel too bad about this static variable, it replaces the
 | 
|---|
| 99 |  * smb_idle_event_list that used to exist in lib/module.c.  -- VL
 | 
|---|
| 100 |  */
 | 
|---|
| 101 | 
 | 
|---|
| 102 | static struct event_context *pdb_event_ctx;
 | 
|---|
| 103 | 
 | 
|---|
| 104 | struct event_context *pdb_get_event_context(void)
 | 
|---|
| 105 | {
 | 
|---|
| 106 |         return pdb_event_ctx;
 | 
|---|
| 107 | }
 | 
|---|
| 108 | 
 | 
|---|
| 109 | /******************************************************************
 | 
|---|
| 110 |   Make a pdb_methods from scratch
 | 
|---|
| 111 |  *******************************************************************/
 | 
|---|
| 112 | 
 | 
|---|
| 113 | NTSTATUS make_pdb_method_name(struct pdb_methods **methods, const char *selected)
 | 
|---|
| 114 | {
 | 
|---|
| 115 |         char *module_name = smb_xstrdup(selected);
 | 
|---|
| 116 |         char *module_location = NULL, *p;
 | 
|---|
| 117 |         struct pdb_init_function_entry *entry;
 | 
|---|
| 118 |         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 | 
|---|
| 119 | 
 | 
|---|
| 120 |         lazy_initialize_passdb();
 | 
|---|
| 121 | 
 | 
|---|
| 122 |         p = strchr(module_name, ':');
 | 
|---|
| 123 | 
 | 
|---|
| 124 |         if (p) {
 | 
|---|
| 125 |                 *p = 0;
 | 
|---|
| 126 |                 module_location = p+1;
 | 
|---|
| 127 |                 trim_char(module_location, ' ', ' ');
 | 
|---|
| 128 |         }
 | 
|---|
| 129 | 
 | 
|---|
| 130 |         trim_char(module_name, ' ', ' ');
 | 
|---|
| 131 | 
 | 
|---|
| 132 | 
 | 
|---|
| 133 |         DEBUG(5,("Attempting to find a passdb backend to match %s (%s)\n", selected, module_name));
 | 
|---|
| 134 | 
 | 
|---|
| 135 |         entry = pdb_find_backend_entry(module_name);
 | 
|---|
| 136 | 
 | 
|---|
| 137 |         /* Try to find a module that contains this module */
 | 
|---|
| 138 |         if (!entry) { 
 | 
|---|
| 139 |                 DEBUG(2,("No builtin backend found, trying to load plugin\n"));
 | 
|---|
| 140 |                 if(NT_STATUS_IS_OK(smb_probe_module("pdb", module_name)) && !(entry = pdb_find_backend_entry(module_name))) {
 | 
|---|
| 141 |                         DEBUG(0,("Plugin is available, but doesn't register passdb backend %s\n", module_name));
 | 
|---|
| 142 |                         SAFE_FREE(module_name);
 | 
|---|
| 143 |                         return NT_STATUS_UNSUCCESSFUL;
 | 
|---|
| 144 |                 }
 | 
|---|
| 145 |         }
 | 
|---|
| 146 | 
 | 
|---|
| 147 |         /* No such backend found */
 | 
|---|
| 148 |         if(!entry) { 
 | 
|---|
| 149 |                 DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
 | 
|---|
| 150 |                 SAFE_FREE(module_name);
 | 
|---|
| 151 |                 return NT_STATUS_INVALID_PARAMETER;
 | 
|---|
| 152 |         }
 | 
|---|
| 153 | 
 | 
|---|
| 154 |         DEBUG(5,("Found pdb backend %s\n", module_name));
 | 
|---|
| 155 | 
 | 
|---|
| 156 |         if ( !NT_STATUS_IS_OK( nt_status = entry->init(methods, module_location) ) ) {
 | 
|---|
| 157 |                 DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", 
 | 
|---|
| 158 |                         selected, nt_errstr(nt_status)));
 | 
|---|
| 159 |                 SAFE_FREE(module_name);
 | 
|---|
| 160 |                 return nt_status;
 | 
|---|
| 161 |         }
 | 
|---|
| 162 | 
 | 
|---|
| 163 |         SAFE_FREE(module_name);
 | 
|---|
| 164 | 
 | 
|---|
| 165 |         DEBUG(5,("pdb backend %s has a valid init\n", selected));
 | 
|---|
| 166 | 
 | 
|---|
| 167 |         return nt_status;
 | 
|---|
| 168 | }
 | 
|---|
| 169 | 
 | 
|---|
| 170 | /******************************************************************
 | 
|---|
| 171 |  Return an already initialized pdb_methods structure
 | 
|---|
| 172 | *******************************************************************/
 | 
|---|
| 173 | 
 | 
|---|
| 174 | static struct pdb_methods *pdb_get_methods_reload( bool reload ) 
 | 
|---|
| 175 | {
 | 
|---|
| 176 |         static struct pdb_methods *pdb = NULL;
 | 
|---|
| 177 | 
 | 
|---|
| 178 |         if ( pdb && reload ) {
 | 
|---|
| 179 |                 pdb->free_private_data( &(pdb->private_data) );
 | 
|---|
| 180 |                 if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
 | 
|---|
| 181 |                         char *msg = NULL;
 | 
|---|
| 182 |                         if (asprintf(&msg, "pdb_get_methods_reload: "
 | 
|---|
| 183 |                                         "failed to get pdb methods for backend %s\n",
 | 
|---|
| 184 |                                         lp_passdb_backend()) > 0) {
 | 
|---|
| 185 |                                 smb_panic(msg);
 | 
|---|
| 186 |                         } else {
 | 
|---|
| 187 |                                 smb_panic("pdb_get_methods_reload");
 | 
|---|
| 188 |                         }
 | 
|---|
| 189 |                 }
 | 
|---|
| 190 |         }
 | 
|---|
| 191 | 
 | 
|---|
| 192 |         if ( !pdb ) {
 | 
|---|
| 193 |                 if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
 | 
|---|
| 194 |                         char *msg = NULL;
 | 
|---|
| 195 |                         if (asprintf(&msg, "pdb_get_methods_reload: "
 | 
|---|
| 196 |                                         "failed to get pdb methods for backend %s\n",
 | 
|---|
| 197 |                                         lp_passdb_backend()) > 0) {
 | 
|---|
| 198 |                                 smb_panic(msg);
 | 
|---|
| 199 |                         } else {
 | 
|---|
| 200 |                                 smb_panic("pdb_get_methods_reload");
 | 
|---|
| 201 |                         }
 | 
|---|
| 202 |                 }
 | 
|---|
| 203 |         }
 | 
|---|
| 204 | 
 | 
|---|
| 205 |         return pdb;
 | 
|---|
| 206 | }
 | 
|---|
| 207 | 
 | 
|---|
| 208 | static struct pdb_methods *pdb_get_methods(void)
 | 
|---|
| 209 | {
 | 
|---|
| 210 |         return pdb_get_methods_reload(False);
 | 
|---|
| 211 | }
 | 
|---|
| 212 | 
 | 
|---|
| 213 | struct pdb_domain_info *pdb_get_domain_info(TALLOC_CTX *mem_ctx)
 | 
|---|
| 214 | {
 | 
|---|
| 215 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 216 |         return pdb->get_domain_info(pdb, mem_ctx);
 | 
|---|
| 217 | }
 | 
|---|
| 218 | 
 | 
|---|
| 219 | bool pdb_getsampwnam(struct samu *sam_acct, const char *username) 
 | 
|---|
| 220 | {
 | 
|---|
| 221 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 222 |         struct samu *for_cache;
 | 
|---|
| 223 |         const struct dom_sid *user_sid;
 | 
|---|
| 224 | 
 | 
|---|
| 225 |         if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
 | 
|---|
| 226 |                 return False;
 | 
|---|
| 227 |         }
 | 
|---|
| 228 | 
 | 
|---|
| 229 |         for_cache = samu_new(NULL);
 | 
|---|
| 230 |         if (for_cache == NULL) {
 | 
|---|
| 231 |                 return False;
 | 
|---|
| 232 |         }
 | 
|---|
| 233 | 
 | 
|---|
| 234 |         if (!pdb_copy_sam_account(for_cache, sam_acct)) {
 | 
|---|
| 235 |                 TALLOC_FREE(for_cache);
 | 
|---|
| 236 |                 return False;
 | 
|---|
| 237 |         }
 | 
|---|
| 238 | 
 | 
|---|
| 239 |         user_sid = pdb_get_user_sid(for_cache);
 | 
|---|
| 240 | 
 | 
|---|
| 241 |         memcache_add_talloc(NULL, PDB_GETPWSID_CACHE,
 | 
|---|
| 242 |                             data_blob_const(user_sid, sizeof(*user_sid)),
 | 
|---|
| 243 |                             &for_cache);
 | 
|---|
| 244 | 
 | 
|---|
| 245 |         return True;
 | 
|---|
| 246 | }
 | 
|---|
| 247 | 
 | 
|---|
| 248 | /**********************************************************************
 | 
|---|
| 249 | **********************************************************************/
 | 
|---|
| 250 | 
 | 
|---|
| 251 | bool guest_user_info( struct samu *user )
 | 
|---|
| 252 | {
 | 
|---|
| 253 |         struct passwd *pwd;
 | 
|---|
| 254 |         NTSTATUS result;
 | 
|---|
| 255 |         const char *guestname = lp_guestaccount();
 | 
|---|
| 256 | 
 | 
|---|
| 257 |         if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), guestname ) ) ) {
 | 
|---|
| 258 |                 DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n", 
 | 
|---|
| 259 |                         guestname));
 | 
|---|
| 260 |                 return False;
 | 
|---|
| 261 |         }
 | 
|---|
| 262 | 
 | 
|---|
| 263 |         result = samu_set_unix(user, pwd );
 | 
|---|
| 264 | 
 | 
|---|
| 265 |         TALLOC_FREE( pwd );
 | 
|---|
| 266 | 
 | 
|---|
| 267 |         return NT_STATUS_IS_OK( result );
 | 
|---|
| 268 | }
 | 
|---|
| 269 | 
 | 
|---|
| 270 | /**********************************************************************
 | 
|---|
| 271 | **********************************************************************/
 | 
|---|
| 272 | 
 | 
|---|
| 273 | bool pdb_getsampwsid(struct samu *sam_acct, const DOM_SID *sid) 
 | 
|---|
| 274 | {
 | 
|---|
| 275 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 276 |         uint32 rid;
 | 
|---|
| 277 |         void *cache_data;
 | 
|---|
| 278 | 
 | 
|---|
| 279 |         /* hard code the Guest RID of 501 */
 | 
|---|
| 280 | 
 | 
|---|
| 281 |         if ( !sid_peek_check_rid( get_global_sam_sid(), sid, &rid ) )
 | 
|---|
| 282 |                 return False;
 | 
|---|
| 283 | 
 | 
|---|
| 284 |         if ( rid == DOMAIN_USER_RID_GUEST ) {
 | 
|---|
| 285 |                 DEBUG(6,("pdb_getsampwsid: Building guest account\n"));
 | 
|---|
| 286 |                 return guest_user_info( sam_acct );
 | 
|---|
| 287 |         }
 | 
|---|
| 288 | 
 | 
|---|
| 289 |         /* check the cache first */
 | 
|---|
| 290 | 
 | 
|---|
| 291 |         cache_data = memcache_lookup_talloc(
 | 
|---|
| 292 |                 NULL, PDB_GETPWSID_CACHE, data_blob_const(sid, sizeof(*sid)));
 | 
|---|
| 293 | 
 | 
|---|
| 294 |         if (cache_data != NULL) {
 | 
|---|
| 295 |                 struct samu *cache_copy = talloc_get_type_abort(
 | 
|---|
| 296 |                         cache_data, struct samu);
 | 
|---|
| 297 | 
 | 
|---|
| 298 |                 return pdb_copy_sam_account(sam_acct, cache_copy);
 | 
|---|
| 299 |         }
 | 
|---|
| 300 | 
 | 
|---|
| 301 |         return NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
 | 
|---|
| 302 | }
 | 
|---|
| 303 | 
 | 
|---|
| 304 | static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
 | 
|---|
| 305 |                                         TALLOC_CTX *tmp_ctx, const char *name,
 | 
|---|
| 306 |                                         uint32 acb_info, uint32 *rid)
 | 
|---|
| 307 | {
 | 
|---|
| 308 |         struct samu *sam_pass;
 | 
|---|
| 309 |         NTSTATUS status;
 | 
|---|
| 310 |         struct passwd *pwd;
 | 
|---|
| 311 | 
 | 
|---|
| 312 |         if ((sam_pass = samu_new(tmp_ctx)) == NULL) {
 | 
|---|
| 313 |                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 314 |         }
 | 
|---|
| 315 | 
 | 
|---|
| 316 |         if ( !(pwd = Get_Pwnam_alloc(tmp_ctx, name)) ) {
 | 
|---|
| 317 |                 char *add_script = NULL;
 | 
|---|
| 318 |                 int add_ret;
 | 
|---|
| 319 |                 fstring name2;
 | 
|---|
| 320 | 
 | 
|---|
| 321 |                 if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] != '$') {
 | 
|---|
| 322 |                         add_script = talloc_strdup(tmp_ctx,
 | 
|---|
| 323 |                                         lp_adduser_script());
 | 
|---|
| 324 |                 } else {
 | 
|---|
| 325 |                         add_script = talloc_strdup(tmp_ctx,
 | 
|---|
| 326 |                                         lp_addmachine_script());
 | 
|---|
| 327 |                 }
 | 
|---|
| 328 | 
 | 
|---|
| 329 |                 if (!add_script || add_script[0] == '\0') {
 | 
|---|
| 330 |                         DEBUG(3, ("Could not find user %s and no add script "
 | 
|---|
| 331 |                                   "defined\n", name));
 | 
|---|
| 332 |                         return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 333 |                 }
 | 
|---|
| 334 | 
 | 
|---|
| 335 |                 /* lowercase the username before creating the Unix account for 
 | 
|---|
| 336 |                    compatibility with previous Samba releases */
 | 
|---|
| 337 |                 fstrcpy( name2, name );
 | 
|---|
| 338 |                 strlower_m( name2 );
 | 
|---|
| 339 |                 add_script = talloc_all_string_sub(tmp_ctx,
 | 
|---|
| 340 |                                         add_script,
 | 
|---|
| 341 |                                         "%u",
 | 
|---|
| 342 |                                         name2);
 | 
|---|
| 343 |                 if (!add_script) {
 | 
|---|
| 344 |                         return NT_STATUS_NO_MEMORY;
 | 
|---|
| 345 |                 }
 | 
|---|
| 346 |                 add_ret = smbrun(add_script,NULL);
 | 
|---|
| 347 |                 DEBUG(add_ret ? 0 : 3, ("_samr_create_user: Running the command `%s' gave %d\n",
 | 
|---|
| 348 |                                         add_script, add_ret));
 | 
|---|
| 349 |                 if (add_ret == 0) {
 | 
|---|
| 350 |                         smb_nscd_flush_user_cache();
 | 
|---|
| 351 |                 }
 | 
|---|
| 352 | 
 | 
|---|
| 353 |                 flush_pwnam_cache();
 | 
|---|
| 354 | 
 | 
|---|
| 355 |                 pwd = Get_Pwnam_alloc(tmp_ctx, name);
 | 
|---|
| 356 |         }
 | 
|---|
| 357 | 
 | 
|---|
| 358 |         /* we have a valid SID coming out of this call */
 | 
|---|
| 359 | 
 | 
|---|
| 360 |         status = samu_alloc_rid_unix( sam_pass, pwd );
 | 
|---|
| 361 | 
 | 
|---|
| 362 |         TALLOC_FREE( pwd );
 | 
|---|
| 363 | 
 | 
|---|
| 364 |         if (!NT_STATUS_IS_OK(status)) {
 | 
|---|
| 365 |                 DEBUG(3, ("pdb_default_create_user: failed to create a new user structure: %s\n", nt_errstr(status)));
 | 
|---|
| 366 |                 return status;
 | 
|---|
| 367 |         }
 | 
|---|
| 368 | 
 | 
|---|
| 369 |         if (!sid_peek_check_rid(get_global_sam_sid(),
 | 
|---|
| 370 |                                 pdb_get_user_sid(sam_pass), rid)) {
 | 
|---|
| 371 |                 DEBUG(0, ("Could not get RID of fresh user\n"));
 | 
|---|
| 372 |                 return NT_STATUS_INTERNAL_ERROR;
 | 
|---|
| 373 |         }
 | 
|---|
| 374 | 
 | 
|---|
| 375 |         /* Use the username case specified in the original request */
 | 
|---|
| 376 | 
 | 
|---|
| 377 |         pdb_set_username( sam_pass, name, PDB_SET );
 | 
|---|
| 378 | 
 | 
|---|
| 379 |         /* Disable the account on creation, it does not have a reasonable password yet. */
 | 
|---|
| 380 | 
 | 
|---|
| 381 |         acb_info |= ACB_DISABLED;
 | 
|---|
| 382 | 
 | 
|---|
| 383 |         pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
 | 
|---|
| 384 | 
 | 
|---|
| 385 |         status = pdb_add_sam_account(sam_pass);
 | 
|---|
| 386 | 
 | 
|---|
| 387 |         TALLOC_FREE(sam_pass);
 | 
|---|
| 388 | 
 | 
|---|
| 389 |         return status;
 | 
|---|
| 390 | }
 | 
|---|
| 391 | 
 | 
|---|
| 392 | NTSTATUS pdb_create_user(TALLOC_CTX *mem_ctx, const char *name, uint32 flags,
 | 
|---|
| 393 |                          uint32 *rid)
 | 
|---|
| 394 | {
 | 
|---|
| 395 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 396 |         return pdb->create_user(pdb, mem_ctx, name, flags, rid);
 | 
|---|
| 397 | }
 | 
|---|
| 398 | 
 | 
|---|
| 399 | /****************************************************************************
 | 
|---|
| 400 |  Delete a UNIX user on demand.
 | 
|---|
| 401 | ****************************************************************************/
 | 
|---|
| 402 | 
 | 
|---|
| 403 | static int smb_delete_user(const char *unix_user)
 | 
|---|
| 404 | {
 | 
|---|
| 405 |         char *del_script = NULL;
 | 
|---|
| 406 |         int ret;
 | 
|---|
| 407 | 
 | 
|---|
| 408 |         /* safety check */
 | 
|---|
| 409 | 
 | 
|---|
| 410 |         if ( strequal( unix_user, "root" ) ) {
 | 
|---|
| 411 |                 DEBUG(0,("smb_delete_user: Refusing to delete local system root account!\n"));
 | 
|---|
| 412 |                 return -1;
 | 
|---|
| 413 |         }
 | 
|---|
| 414 | 
 | 
|---|
| 415 |         del_script = talloc_strdup(talloc_tos(), lp_deluser_script());
 | 
|---|
| 416 |         if (!del_script || !*del_script) {
 | 
|---|
| 417 |                 return -1;
 | 
|---|
| 418 |         }
 | 
|---|
| 419 |         del_script = talloc_all_string_sub(talloc_tos(),
 | 
|---|
| 420 |                                 del_script,
 | 
|---|
| 421 |                                 "%u",
 | 
|---|
| 422 |                                 unix_user);
 | 
|---|
| 423 |         if (!del_script) {
 | 
|---|
| 424 |                 return -1;
 | 
|---|
| 425 |         }
 | 
|---|
| 426 |         ret = smbrun(del_script,NULL);
 | 
|---|
| 427 |         flush_pwnam_cache();
 | 
|---|
| 428 |         if (ret == 0) {
 | 
|---|
| 429 |                 smb_nscd_flush_user_cache();
 | 
|---|
| 430 |         }
 | 
|---|
| 431 |         DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
 | 
|---|
| 432 | 
 | 
|---|
| 433 |         return ret;
 | 
|---|
| 434 | }
 | 
|---|
| 435 | 
 | 
|---|
| 436 | static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods,
 | 
|---|
| 437 |                                         TALLOC_CTX *mem_ctx,
 | 
|---|
| 438 |                                         struct samu *sam_acct)
 | 
|---|
| 439 | {
 | 
|---|
| 440 |         NTSTATUS status;
 | 
|---|
| 441 |         fstring username;
 | 
|---|
| 442 | 
 | 
|---|
| 443 |         status = pdb_delete_sam_account(sam_acct);
 | 
|---|
| 444 |         if (!NT_STATUS_IS_OK(status)) {
 | 
|---|
| 445 |                 return status;
 | 
|---|
| 446 |         }
 | 
|---|
| 447 | 
 | 
|---|
| 448 |         /*
 | 
|---|
| 449 |          * Now delete the unix side ....
 | 
|---|
| 450 |          * note: we don't check if the delete really happened as the script is
 | 
|---|
| 451 |          * not necessary present and maybe the sysadmin doesn't want to delete
 | 
|---|
| 452 |          * the unix side
 | 
|---|
| 453 |          */
 | 
|---|
| 454 | 
 | 
|---|
| 455 |         /* always lower case the username before handing it off to 
 | 
|---|
| 456 |            external scripts */
 | 
|---|
| 457 | 
 | 
|---|
| 458 |         fstrcpy( username, pdb_get_username(sam_acct) );
 | 
|---|
| 459 |         strlower_m( username );
 | 
|---|
| 460 | 
 | 
|---|
| 461 |         smb_delete_user( username );
 | 
|---|
| 462 | 
 | 
|---|
| 463 |         return status;
 | 
|---|
| 464 | }
 | 
|---|
| 465 | 
 | 
|---|
| 466 | NTSTATUS pdb_delete_user(TALLOC_CTX *mem_ctx, struct samu *sam_acct)
 | 
|---|
| 467 | {
 | 
|---|
| 468 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 469 |         uid_t uid = -1;
 | 
|---|
| 470 | 
 | 
|---|
| 471 |         /* sanity check to make sure we don't delete root */
 | 
|---|
| 472 | 
 | 
|---|
| 473 |         if ( !sid_to_uid( pdb_get_user_sid(sam_acct), &uid ) ) {
 | 
|---|
| 474 |                 return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 475 |         }
 | 
|---|
| 476 | 
 | 
|---|
| 477 |         if ( uid == 0 ) {
 | 
|---|
| 478 |                 return NT_STATUS_ACCESS_DENIED;
 | 
|---|
| 479 |         }
 | 
|---|
| 480 | 
 | 
|---|
| 481 |         return pdb->delete_user(pdb, mem_ctx, sam_acct);
 | 
|---|
| 482 | }
 | 
|---|
| 483 | 
 | 
|---|
| 484 | NTSTATUS pdb_add_sam_account(struct samu *sam_acct) 
 | 
|---|
| 485 | {
 | 
|---|
| 486 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 487 |         return pdb->add_sam_account(pdb, sam_acct);
 | 
|---|
| 488 | }
 | 
|---|
| 489 | 
 | 
|---|
| 490 | NTSTATUS pdb_update_sam_account(struct samu *sam_acct) 
 | 
|---|
| 491 | {
 | 
|---|
| 492 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 493 | 
 | 
|---|
| 494 |         memcache_flush(NULL, PDB_GETPWSID_CACHE);
 | 
|---|
| 495 | 
 | 
|---|
| 496 |         return pdb->update_sam_account(pdb, sam_acct);
 | 
|---|
| 497 | }
 | 
|---|
| 498 | 
 | 
|---|
| 499 | NTSTATUS pdb_delete_sam_account(struct samu *sam_acct) 
 | 
|---|
| 500 | {
 | 
|---|
| 501 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 502 | 
 | 
|---|
| 503 |         memcache_flush(NULL, PDB_GETPWSID_CACHE);
 | 
|---|
| 504 | 
 | 
|---|
| 505 |         return pdb->delete_sam_account(pdb, sam_acct);
 | 
|---|
| 506 | }
 | 
|---|
| 507 | 
 | 
|---|
| 508 | NTSTATUS pdb_rename_sam_account(struct samu *oldname, const char *newname)
 | 
|---|
| 509 | {
 | 
|---|
| 510 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 511 |         uid_t uid;
 | 
|---|
| 512 |         NTSTATUS status;
 | 
|---|
| 513 | 
 | 
|---|
| 514 |         memcache_flush(NULL, PDB_GETPWSID_CACHE);
 | 
|---|
| 515 | 
 | 
|---|
| 516 |         /* sanity check to make sure we don't rename root */
 | 
|---|
| 517 | 
 | 
|---|
| 518 |         if ( !sid_to_uid( pdb_get_user_sid(oldname), &uid ) ) {
 | 
|---|
| 519 |                 return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 520 |         }
 | 
|---|
| 521 | 
 | 
|---|
| 522 |         if ( uid == 0 ) {
 | 
|---|
| 523 |                 return NT_STATUS_ACCESS_DENIED;
 | 
|---|
| 524 |         }
 | 
|---|
| 525 | 
 | 
|---|
| 526 |         status = pdb->rename_sam_account(pdb, oldname, newname);
 | 
|---|
| 527 | 
 | 
|---|
| 528 |         /* always flush the cache here just to be safe */
 | 
|---|
| 529 |         flush_pwnam_cache();
 | 
|---|
| 530 | 
 | 
|---|
| 531 |         return status;
 | 
|---|
| 532 | }
 | 
|---|
| 533 | 
 | 
|---|
| 534 | NTSTATUS pdb_update_login_attempts(struct samu *sam_acct, bool success)
 | 
|---|
| 535 | {
 | 
|---|
| 536 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 537 |         return pdb->update_login_attempts(pdb, sam_acct, success);
 | 
|---|
| 538 | }
 | 
|---|
| 539 | 
 | 
|---|
| 540 | bool pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
 | 
|---|
| 541 | {
 | 
|---|
| 542 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 543 |         return NT_STATUS_IS_OK(pdb->getgrsid(pdb, map, sid));
 | 
|---|
| 544 | }
 | 
|---|
| 545 | 
 | 
|---|
| 546 | bool pdb_getgrgid(GROUP_MAP *map, gid_t gid)
 | 
|---|
| 547 | {
 | 
|---|
| 548 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 549 |         return NT_STATUS_IS_OK(pdb->getgrgid(pdb, map, gid));
 | 
|---|
| 550 | }
 | 
|---|
| 551 | 
 | 
|---|
| 552 | bool pdb_getgrnam(GROUP_MAP *map, const char *name)
 | 
|---|
| 553 | {
 | 
|---|
| 554 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 555 |         return NT_STATUS_IS_OK(pdb->getgrnam(pdb, map, name));
 | 
|---|
| 556 | }
 | 
|---|
| 557 | 
 | 
|---|
| 558 | static NTSTATUS pdb_default_create_dom_group(struct pdb_methods *methods,
 | 
|---|
| 559 |                                              TALLOC_CTX *mem_ctx,
 | 
|---|
| 560 |                                              const char *name,
 | 
|---|
| 561 |                                              uint32 *rid)
 | 
|---|
| 562 | {
 | 
|---|
| 563 |         DOM_SID group_sid;
 | 
|---|
| 564 |         struct group *grp;
 | 
|---|
| 565 |         fstring tmp;
 | 
|---|
| 566 | 
 | 
|---|
| 567 |         grp = getgrnam(name);
 | 
|---|
| 568 | 
 | 
|---|
| 569 |         if (grp == NULL) {
 | 
|---|
| 570 |                 gid_t gid;
 | 
|---|
| 571 | 
 | 
|---|
| 572 |                 if (smb_create_group(name, &gid) != 0) {
 | 
|---|
| 573 |                         return NT_STATUS_ACCESS_DENIED;
 | 
|---|
| 574 |                 }
 | 
|---|
| 575 | 
 | 
|---|
| 576 |                 grp = getgrgid(gid);
 | 
|---|
| 577 |         }
 | 
|---|
| 578 | 
 | 
|---|
| 579 |         if (grp == NULL) {
 | 
|---|
| 580 |                 return NT_STATUS_ACCESS_DENIED;
 | 
|---|
| 581 |         }
 | 
|---|
| 582 | 
 | 
|---|
| 583 |         if (pdb_capabilities() & PDB_CAP_STORE_RIDS) {
 | 
|---|
| 584 |                 if (!pdb_new_rid(rid)) {
 | 
|---|
| 585 |                         return NT_STATUS_ACCESS_DENIED;
 | 
|---|
| 586 |                 }
 | 
|---|
| 587 |         } else {
 | 
|---|
| 588 |                 *rid = algorithmic_pdb_gid_to_group_rid( grp->gr_gid );
 | 
|---|
| 589 |         }
 | 
|---|
| 590 | 
 | 
|---|
| 591 |         sid_compose(&group_sid, get_global_sam_sid(), *rid);
 | 
|---|
| 592 | 
 | 
|---|
| 593 |         return add_initial_entry(grp->gr_gid, sid_to_fstring(tmp, &group_sid),
 | 
|---|
| 594 |                                  SID_NAME_DOM_GRP, name, NULL);
 | 
|---|
| 595 | }
 | 
|---|
| 596 | 
 | 
|---|
| 597 | NTSTATUS pdb_create_dom_group(TALLOC_CTX *mem_ctx, const char *name,
 | 
|---|
| 598 |                               uint32 *rid)
 | 
|---|
| 599 | {
 | 
|---|
| 600 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 601 |         return pdb->create_dom_group(pdb, mem_ctx, name, rid);
 | 
|---|
| 602 | }
 | 
|---|
| 603 | 
 | 
|---|
| 604 | static NTSTATUS pdb_default_delete_dom_group(struct pdb_methods *methods,
 | 
|---|
| 605 |                                              TALLOC_CTX *mem_ctx,
 | 
|---|
| 606 |                                              uint32 rid)
 | 
|---|
| 607 | {
 | 
|---|
| 608 |         DOM_SID group_sid;
 | 
|---|
| 609 |         GROUP_MAP map;
 | 
|---|
| 610 |         NTSTATUS status;
 | 
|---|
| 611 |         struct group *grp;
 | 
|---|
| 612 |         const char *grp_name;
 | 
|---|
| 613 | 
 | 
|---|
| 614 |         /* coverity */
 | 
|---|
| 615 |         map.gid = (gid_t) -1;
 | 
|---|
| 616 | 
 | 
|---|
| 617 |         sid_compose(&group_sid, get_global_sam_sid(), rid);
 | 
|---|
| 618 | 
 | 
|---|
| 619 |         if (!get_domain_group_from_sid(group_sid, &map)) {
 | 
|---|
| 620 |                 DEBUG(10, ("Could not find group for rid %d\n", rid));
 | 
|---|
| 621 |                 return NT_STATUS_NO_SUCH_GROUP;
 | 
|---|
| 622 |         }
 | 
|---|
| 623 | 
 | 
|---|
| 624 |         /* We need the group name for the smb_delete_group later on */
 | 
|---|
| 625 | 
 | 
|---|
| 626 |         if (map.gid == (gid_t)-1) {
 | 
|---|
| 627 |                 return NT_STATUS_NO_SUCH_GROUP;
 | 
|---|
| 628 |         }
 | 
|---|
| 629 | 
 | 
|---|
| 630 |         grp = getgrgid(map.gid);
 | 
|---|
| 631 |         if (grp == NULL) {
 | 
|---|
| 632 |                 return NT_STATUS_NO_SUCH_GROUP;
 | 
|---|
| 633 |         }
 | 
|---|
| 634 | 
 | 
|---|
| 635 |         /* Copy the name, no idea what pdb_delete_group_mapping_entry does.. */
 | 
|---|
| 636 | 
 | 
|---|
| 637 |         grp_name = talloc_strdup(mem_ctx, grp->gr_name);
 | 
|---|
| 638 |         if (grp_name == NULL) {
 | 
|---|
| 639 |                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 640 |         }
 | 
|---|
| 641 | 
 | 
|---|
| 642 |         status = pdb_delete_group_mapping_entry(group_sid);
 | 
|---|
| 643 | 
 | 
|---|
| 644 |         if (!NT_STATUS_IS_OK(status)) {
 | 
|---|
| 645 |                 return status;
 | 
|---|
| 646 |         }
 | 
|---|
| 647 | 
 | 
|---|
| 648 |         /* Don't check the result of smb_delete_group */
 | 
|---|
| 649 | 
 | 
|---|
| 650 |         smb_delete_group(grp_name);
 | 
|---|
| 651 | 
 | 
|---|
| 652 |         return NT_STATUS_OK;
 | 
|---|
| 653 | }
 | 
|---|
| 654 | 
 | 
|---|
| 655 | NTSTATUS pdb_delete_dom_group(TALLOC_CTX *mem_ctx, uint32 rid)
 | 
|---|
| 656 | {
 | 
|---|
| 657 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 658 |         return pdb->delete_dom_group(pdb, mem_ctx, rid);
 | 
|---|
| 659 | }
 | 
|---|
| 660 | 
 | 
|---|
| 661 | NTSTATUS pdb_add_group_mapping_entry(GROUP_MAP *map)
 | 
|---|
| 662 | {
 | 
|---|
| 663 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 664 |         return pdb->add_group_mapping_entry(pdb, map);
 | 
|---|
| 665 | }
 | 
|---|
| 666 | 
 | 
|---|
| 667 | NTSTATUS pdb_update_group_mapping_entry(GROUP_MAP *map)
 | 
|---|
| 668 | {
 | 
|---|
| 669 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 670 |         return pdb->update_group_mapping_entry(pdb, map);
 | 
|---|
| 671 | }
 | 
|---|
| 672 | 
 | 
|---|
| 673 | NTSTATUS pdb_delete_group_mapping_entry(DOM_SID sid)
 | 
|---|
| 674 | {
 | 
|---|
| 675 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 676 |         return pdb->delete_group_mapping_entry(pdb, sid);
 | 
|---|
| 677 | }
 | 
|---|
| 678 | 
 | 
|---|
| 679 | bool pdb_enum_group_mapping(const DOM_SID *sid, enum lsa_SidType sid_name_use, GROUP_MAP **pp_rmap,
 | 
|---|
| 680 |                             size_t *p_num_entries, bool unix_only)
 | 
|---|
| 681 | {
 | 
|---|
| 682 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 683 |         return NT_STATUS_IS_OK(pdb-> enum_group_mapping(pdb, sid, sid_name_use,
 | 
|---|
| 684 |                 pp_rmap, p_num_entries, unix_only));
 | 
|---|
| 685 | }
 | 
|---|
| 686 | 
 | 
|---|
| 687 | NTSTATUS pdb_enum_group_members(TALLOC_CTX *mem_ctx,
 | 
|---|
| 688 |                                 const DOM_SID *sid,
 | 
|---|
| 689 |                                 uint32 **pp_member_rids,
 | 
|---|
| 690 |                                 size_t *p_num_members)
 | 
|---|
| 691 | {
 | 
|---|
| 692 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 693 |         NTSTATUS result;
 | 
|---|
| 694 | 
 | 
|---|
| 695 |         result = pdb->enum_group_members(pdb, mem_ctx, 
 | 
|---|
| 696 |                         sid, pp_member_rids, p_num_members);
 | 
|---|
| 697 | 
 | 
|---|
| 698 |         /* special check for rid 513 */
 | 
|---|
| 699 | 
 | 
|---|
| 700 |         if ( !NT_STATUS_IS_OK( result ) ) {
 | 
|---|
| 701 |                 uint32 rid;
 | 
|---|
| 702 | 
 | 
|---|
| 703 |                 sid_peek_rid( sid, &rid );
 | 
|---|
| 704 | 
 | 
|---|
| 705 |                 if ( rid == DOMAIN_GROUP_RID_USERS ) {
 | 
|---|
| 706 |                         *p_num_members = 0;
 | 
|---|
| 707 |                         *pp_member_rids = NULL;
 | 
|---|
| 708 | 
 | 
|---|
| 709 |                         return NT_STATUS_OK;
 | 
|---|
| 710 |                 }
 | 
|---|
| 711 |         }
 | 
|---|
| 712 | 
 | 
|---|
| 713 |         return result;
 | 
|---|
| 714 | }
 | 
|---|
| 715 | 
 | 
|---|
| 716 | NTSTATUS pdb_enum_group_memberships(TALLOC_CTX *mem_ctx, struct samu *user,
 | 
|---|
| 717 |                                     DOM_SID **pp_sids, gid_t **pp_gids,
 | 
|---|
| 718 |                                     size_t *p_num_groups)
 | 
|---|
| 719 | {
 | 
|---|
| 720 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 721 |         return pdb->enum_group_memberships(
 | 
|---|
| 722 |                 pdb, mem_ctx, user,
 | 
|---|
| 723 |                 pp_sids, pp_gids, p_num_groups);
 | 
|---|
| 724 | }
 | 
|---|
| 725 | 
 | 
|---|
| 726 | static NTSTATUS pdb_default_set_unix_primary_group(struct pdb_methods *methods,
 | 
|---|
| 727 |                                                    TALLOC_CTX *mem_ctx,
 | 
|---|
| 728 |                                                    struct samu *sampass)
 | 
|---|
| 729 | {
 | 
|---|
| 730 |         struct group *grp;
 | 
|---|
| 731 |         gid_t gid;
 | 
|---|
| 732 | 
 | 
|---|
| 733 |         if (!sid_to_gid(pdb_get_group_sid(sampass), &gid) ||
 | 
|---|
| 734 |             (grp = getgrgid(gid)) == NULL) {
 | 
|---|
| 735 |                 return NT_STATUS_INVALID_PRIMARY_GROUP;
 | 
|---|
| 736 |         }
 | 
|---|
| 737 | 
 | 
|---|
| 738 |         if (smb_set_primary_group(grp->gr_name,
 | 
|---|
| 739 |                                   pdb_get_username(sampass)) != 0) {
 | 
|---|
| 740 |                 return NT_STATUS_ACCESS_DENIED;
 | 
|---|
| 741 |         }
 | 
|---|
| 742 | 
 | 
|---|
| 743 |         return NT_STATUS_OK;
 | 
|---|
| 744 | }
 | 
|---|
| 745 | 
 | 
|---|
| 746 | NTSTATUS pdb_set_unix_primary_group(TALLOC_CTX *mem_ctx, struct samu *user)
 | 
|---|
| 747 | {
 | 
|---|
| 748 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 749 |         return pdb->set_unix_primary_group(pdb, mem_ctx, user);
 | 
|---|
| 750 | }
 | 
|---|
| 751 | 
 | 
|---|
| 752 | /*
 | 
|---|
| 753 |  * Helper function to see whether a user is in a group. We can't use
 | 
|---|
| 754 |  * user_in_group_sid here because this creates dependencies only smbd can
 | 
|---|
| 755 |  * fulfil.
 | 
|---|
| 756 |  */
 | 
|---|
| 757 | 
 | 
|---|
| 758 | static bool pdb_user_in_group(TALLOC_CTX *mem_ctx, struct samu *account,
 | 
|---|
| 759 |                               const DOM_SID *group_sid)
 | 
|---|
| 760 | {
 | 
|---|
| 761 |         DOM_SID *sids;
 | 
|---|
| 762 |         gid_t *gids;
 | 
|---|
| 763 |         size_t i, num_groups;
 | 
|---|
| 764 | 
 | 
|---|
| 765 |         if (!NT_STATUS_IS_OK(pdb_enum_group_memberships(mem_ctx, account,
 | 
|---|
| 766 |                                                         &sids, &gids,
 | 
|---|
| 767 |                                                         &num_groups))) {
 | 
|---|
| 768 |                 return False;
 | 
|---|
| 769 |         }
 | 
|---|
| 770 | 
 | 
|---|
| 771 |         for (i=0; i<num_groups; i++) {
 | 
|---|
| 772 |                 if (sid_equal(group_sid, &sids[i])) {
 | 
|---|
| 773 |                         return True;
 | 
|---|
| 774 |                 }
 | 
|---|
| 775 |         }
 | 
|---|
| 776 |         return False;
 | 
|---|
| 777 | }
 | 
|---|
| 778 | 
 | 
|---|
| 779 | static NTSTATUS pdb_default_add_groupmem(struct pdb_methods *methods,
 | 
|---|
| 780 |                                          TALLOC_CTX *mem_ctx,
 | 
|---|
| 781 |                                          uint32 group_rid,
 | 
|---|
| 782 |                                          uint32 member_rid)
 | 
|---|
| 783 | {
 | 
|---|
| 784 |         DOM_SID group_sid, member_sid;
 | 
|---|
| 785 |         struct samu *account = NULL;
 | 
|---|
| 786 |         GROUP_MAP map;
 | 
|---|
| 787 |         struct group *grp;
 | 
|---|
| 788 |         struct passwd *pwd;
 | 
|---|
| 789 |         const char *group_name;
 | 
|---|
| 790 |         uid_t uid;
 | 
|---|
| 791 | 
 | 
|---|
| 792 |         /* coverity */
 | 
|---|
| 793 |         map.gid = (gid_t) -1;
 | 
|---|
| 794 | 
 | 
|---|
| 795 |         sid_compose(&group_sid, get_global_sam_sid(), group_rid);
 | 
|---|
| 796 |         sid_compose(&member_sid, get_global_sam_sid(), member_rid);
 | 
|---|
| 797 | 
 | 
|---|
| 798 |         if (!get_domain_group_from_sid(group_sid, &map) ||
 | 
|---|
| 799 |             (map.gid == (gid_t)-1) ||
 | 
|---|
| 800 |             ((grp = getgrgid(map.gid)) == NULL)) {
 | 
|---|
| 801 |                 return NT_STATUS_NO_SUCH_GROUP;
 | 
|---|
| 802 |         }
 | 
|---|
| 803 | 
 | 
|---|
| 804 |         group_name = talloc_strdup(mem_ctx, grp->gr_name);
 | 
|---|
| 805 |         if (group_name == NULL) {
 | 
|---|
| 806 |                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 807 |         }
 | 
|---|
| 808 | 
 | 
|---|
| 809 |         if ( !(account = samu_new( NULL )) ) {
 | 
|---|
| 810 |                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 811 |         }
 | 
|---|
| 812 | 
 | 
|---|
| 813 |         if (!pdb_getsampwsid(account, &member_sid) ||
 | 
|---|
| 814 |             !sid_to_uid(&member_sid, &uid) ||
 | 
|---|
| 815 |             ((pwd = getpwuid_alloc(mem_ctx, uid)) == NULL)) {
 | 
|---|
| 816 |                 return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 817 |         }
 | 
|---|
| 818 | 
 | 
|---|
| 819 |         if (pdb_user_in_group(mem_ctx, account, &group_sid)) {
 | 
|---|
| 820 |                 return NT_STATUS_MEMBER_IN_GROUP;
 | 
|---|
| 821 |         }
 | 
|---|
| 822 | 
 | 
|---|
| 823 |         /* 
 | 
|---|
| 824 |          * ok, the group exist, the user exist, the user is not in the group,
 | 
|---|
| 825 |          * we can (finally) add it to the group !
 | 
|---|
| 826 |          */
 | 
|---|
| 827 | 
 | 
|---|
| 828 |         smb_add_user_group(group_name, pwd->pw_name);
 | 
|---|
| 829 | 
 | 
|---|
| 830 |         if (!pdb_user_in_group(mem_ctx, account, &group_sid)) {
 | 
|---|
| 831 |                 return NT_STATUS_ACCESS_DENIED;
 | 
|---|
| 832 |         }
 | 
|---|
| 833 | 
 | 
|---|
| 834 |         return NT_STATUS_OK;
 | 
|---|
| 835 | }
 | 
|---|
| 836 | 
 | 
|---|
| 837 | NTSTATUS pdb_add_groupmem(TALLOC_CTX *mem_ctx, uint32 group_rid,
 | 
|---|
| 838 |                           uint32 member_rid)
 | 
|---|
| 839 | {
 | 
|---|
| 840 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 841 |         return pdb->add_groupmem(pdb, mem_ctx, group_rid, member_rid);
 | 
|---|
| 842 | }
 | 
|---|
| 843 | 
 | 
|---|
| 844 | static NTSTATUS pdb_default_del_groupmem(struct pdb_methods *methods,
 | 
|---|
| 845 |                                          TALLOC_CTX *mem_ctx,
 | 
|---|
| 846 |                                          uint32 group_rid,
 | 
|---|
| 847 |                                          uint32 member_rid)
 | 
|---|
| 848 | {
 | 
|---|
| 849 |         DOM_SID group_sid, member_sid;
 | 
|---|
| 850 |         struct samu *account = NULL;
 | 
|---|
| 851 |         GROUP_MAP map;
 | 
|---|
| 852 |         struct group *grp;
 | 
|---|
| 853 |         struct passwd *pwd;
 | 
|---|
| 854 |         const char *group_name;
 | 
|---|
| 855 |         uid_t uid;
 | 
|---|
| 856 | 
 | 
|---|
| 857 |         sid_compose(&group_sid, get_global_sam_sid(), group_rid);
 | 
|---|
| 858 |         sid_compose(&member_sid, get_global_sam_sid(), member_rid);
 | 
|---|
| 859 | 
 | 
|---|
| 860 |         if (!get_domain_group_from_sid(group_sid, &map) ||
 | 
|---|
| 861 |             (map.gid == (gid_t)-1) ||
 | 
|---|
| 862 |             ((grp = getgrgid(map.gid)) == NULL)) {
 | 
|---|
| 863 |                 return NT_STATUS_NO_SUCH_GROUP;
 | 
|---|
| 864 |         }
 | 
|---|
| 865 | 
 | 
|---|
| 866 |         group_name = talloc_strdup(mem_ctx, grp->gr_name);
 | 
|---|
| 867 |         if (group_name == NULL) {
 | 
|---|
| 868 |                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 869 |         }
 | 
|---|
| 870 | 
 | 
|---|
| 871 |         if ( !(account = samu_new( NULL )) ) {
 | 
|---|
| 872 |                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 873 |         }
 | 
|---|
| 874 | 
 | 
|---|
| 875 |         if (!pdb_getsampwsid(account, &member_sid) ||
 | 
|---|
| 876 |             !sid_to_uid(&member_sid, &uid) ||
 | 
|---|
| 877 |             ((pwd = getpwuid_alloc(mem_ctx, uid)) == NULL)) {
 | 
|---|
| 878 |                 return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 879 |         }
 | 
|---|
| 880 | 
 | 
|---|
| 881 |         if (!pdb_user_in_group(mem_ctx, account, &group_sid)) {
 | 
|---|
| 882 |                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
 | 
|---|
| 883 |         }
 | 
|---|
| 884 | 
 | 
|---|
| 885 |         /* 
 | 
|---|
| 886 |          * ok, the group exist, the user exist, the user is in the group,
 | 
|---|
| 887 |          * we can (finally) delete it from the group!
 | 
|---|
| 888 |          */
 | 
|---|
| 889 | 
 | 
|---|
| 890 |         smb_delete_user_group(group_name, pwd->pw_name);
 | 
|---|
| 891 | 
 | 
|---|
| 892 |         if (pdb_user_in_group(mem_ctx, account, &group_sid)) {
 | 
|---|
| 893 |                 return NT_STATUS_ACCESS_DENIED;
 | 
|---|
| 894 |         }
 | 
|---|
| 895 | 
 | 
|---|
| 896 |         return NT_STATUS_OK;
 | 
|---|
| 897 | }
 | 
|---|
| 898 | 
 | 
|---|
| 899 | NTSTATUS pdb_del_groupmem(TALLOC_CTX *mem_ctx, uint32 group_rid,
 | 
|---|
| 900 |                           uint32 member_rid)
 | 
|---|
| 901 | {
 | 
|---|
| 902 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 903 |         return pdb->del_groupmem(pdb, mem_ctx, group_rid, member_rid);
 | 
|---|
| 904 | }
 | 
|---|
| 905 | 
 | 
|---|
| 906 | NTSTATUS pdb_create_alias(const char *name, uint32 *rid)
 | 
|---|
| 907 | {
 | 
|---|
| 908 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 909 |         return pdb->create_alias(pdb, name, rid);
 | 
|---|
| 910 | }
 | 
|---|
| 911 | 
 | 
|---|
| 912 | NTSTATUS pdb_delete_alias(const DOM_SID *sid)
 | 
|---|
| 913 | {
 | 
|---|
| 914 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 915 |         return pdb->delete_alias(pdb, sid);
 | 
|---|
| 916 | }
 | 
|---|
| 917 | 
 | 
|---|
| 918 | NTSTATUS pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
 | 
|---|
| 919 | {
 | 
|---|
| 920 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 921 |         return pdb->get_aliasinfo(pdb, sid, info);
 | 
|---|
| 922 | }
 | 
|---|
| 923 | 
 | 
|---|
| 924 | NTSTATUS pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
 | 
|---|
| 925 | {
 | 
|---|
| 926 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 927 |         return pdb->set_aliasinfo(pdb, sid, info);
 | 
|---|
| 928 | }
 | 
|---|
| 929 | 
 | 
|---|
| 930 | NTSTATUS pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
 | 
|---|
| 931 | {
 | 
|---|
| 932 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 933 |         return pdb->add_aliasmem(pdb, alias, member);
 | 
|---|
| 934 | }
 | 
|---|
| 935 | 
 | 
|---|
| 936 | NTSTATUS pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
 | 
|---|
| 937 | {
 | 
|---|
| 938 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 939 |         return pdb->del_aliasmem(pdb, alias, member);
 | 
|---|
| 940 | }
 | 
|---|
| 941 | 
 | 
|---|
| 942 | NTSTATUS pdb_enum_aliasmem(const DOM_SID *alias, TALLOC_CTX *mem_ctx,
 | 
|---|
| 943 |                            DOM_SID **pp_members, size_t *p_num_members)
 | 
|---|
| 944 | {
 | 
|---|
| 945 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 946 |         return pdb->enum_aliasmem(pdb, alias, mem_ctx, pp_members,
 | 
|---|
| 947 |                                   p_num_members);
 | 
|---|
| 948 | }
 | 
|---|
| 949 | 
 | 
|---|
| 950 | NTSTATUS pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx,
 | 
|---|
| 951 |                                     const DOM_SID *domain_sid,
 | 
|---|
| 952 |                                     const DOM_SID *members, size_t num_members,
 | 
|---|
| 953 |                                     uint32 **pp_alias_rids,
 | 
|---|
| 954 |                                     size_t *p_num_alias_rids)
 | 
|---|
| 955 | {
 | 
|---|
| 956 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 957 |         return pdb->enum_alias_memberships(pdb, mem_ctx,
 | 
|---|
| 958 |                                                        domain_sid,
 | 
|---|
| 959 |                                                        members, num_members,
 | 
|---|
| 960 |                                                        pp_alias_rids,
 | 
|---|
| 961 |                                                        p_num_alias_rids);
 | 
|---|
| 962 | }
 | 
|---|
| 963 | 
 | 
|---|
| 964 | NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
 | 
|---|
| 965 |                          int num_rids,
 | 
|---|
| 966 |                          uint32 *rids,
 | 
|---|
| 967 |                          const char **names,
 | 
|---|
| 968 |                          enum lsa_SidType *attrs)
 | 
|---|
| 969 | {
 | 
|---|
| 970 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 971 |         return pdb->lookup_rids(pdb, domain_sid, num_rids, rids, names, attrs);
 | 
|---|
| 972 | }
 | 
|---|
| 973 | 
 | 
|---|
| 974 | /* 
 | 
|---|
| 975 |  * NOTE: pdb_lookup_names is currently (2007-01-12) not used anywhere 
 | 
|---|
| 976 |  *       in the samba code.
 | 
|---|
| 977 |  *       Unlike _lsa_lookup_sids and _samr_lookup_rids, which eventually 
 | 
|---|
| 978 |  *       also ask pdb_lookup_rids, thus looking up a bunch of rids at a time, 
 | 
|---|
| 979 |  *       the pdb_ calls _lsa_lookup_names and _samr_lookup_names come
 | 
|---|
| 980 |  *       down to are pdb_getsampwnam and pdb_getgrnam instead of
 | 
|---|
| 981 |  *       pdb_lookup_names.
 | 
|---|
| 982 |  *       But in principle, it the call belongs to the API and might get
 | 
|---|
| 983 |  *       used in this context some day. 
 | 
|---|
| 984 |  */
 | 
|---|
| 985 | #if 0
 | 
|---|
| 986 | NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
 | 
|---|
| 987 |                           int num_names,
 | 
|---|
| 988 |                           const char **names,
 | 
|---|
| 989 |                           uint32 *rids,
 | 
|---|
| 990 |                           enum lsa_SidType *attrs)
 | 
|---|
| 991 | {
 | 
|---|
| 992 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 993 |         return pdb->lookup_names(pdb, domain_sid, num_names, names, rids, attrs);
 | 
|---|
| 994 | }
 | 
|---|
| 995 | #endif
 | 
|---|
| 996 | 
 | 
|---|
| 997 | bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value)
 | 
|---|
| 998 | {
 | 
|---|
| 999 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1000 |         NTSTATUS status;
 | 
|---|
| 1001 | 
 | 
|---|
| 1002 |         become_root();
 | 
|---|
| 1003 |         status = pdb->get_account_policy(pdb, type, value);
 | 
|---|
| 1004 |         unbecome_root();
 | 
|---|
| 1005 | 
 | 
|---|
| 1006 |         return NT_STATUS_IS_OK(status); 
 | 
|---|
| 1007 | }
 | 
|---|
| 1008 | 
 | 
|---|
| 1009 | bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value)
 | 
|---|
| 1010 | {
 | 
|---|
| 1011 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1012 |         NTSTATUS status;
 | 
|---|
| 1013 | 
 | 
|---|
| 1014 |         become_root();
 | 
|---|
| 1015 |         status = pdb->set_account_policy(pdb, type, value);
 | 
|---|
| 1016 |         unbecome_root();
 | 
|---|
| 1017 | 
 | 
|---|
| 1018 |         return NT_STATUS_IS_OK(status);
 | 
|---|
| 1019 | }
 | 
|---|
| 1020 | 
 | 
|---|
| 1021 | bool pdb_get_seq_num(time_t *seq_num)
 | 
|---|
| 1022 | {
 | 
|---|
| 1023 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1024 |         return NT_STATUS_IS_OK(pdb->get_seq_num(pdb, seq_num));
 | 
|---|
| 1025 | }
 | 
|---|
| 1026 | 
 | 
|---|
| 1027 | bool pdb_uid_to_sid(uid_t uid, DOM_SID *sid)
 | 
|---|
| 1028 | {
 | 
|---|
| 1029 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1030 |         return pdb->uid_to_sid(pdb, uid, sid);
 | 
|---|
| 1031 | }
 | 
|---|
| 1032 | 
 | 
|---|
| 1033 | bool pdb_gid_to_sid(gid_t gid, DOM_SID *sid)
 | 
|---|
| 1034 | {
 | 
|---|
| 1035 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1036 |         return pdb->gid_to_sid(pdb, gid, sid);
 | 
|---|
| 1037 | }
 | 
|---|
| 1038 | 
 | 
|---|
| 1039 | bool pdb_sid_to_id(const DOM_SID *sid, union unid_t *id,
 | 
|---|
| 1040 |                    enum lsa_SidType *type)
 | 
|---|
| 1041 | {
 | 
|---|
| 1042 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1043 |         return pdb->sid_to_id(pdb, sid, id, type);
 | 
|---|
| 1044 | }
 | 
|---|
| 1045 | 
 | 
|---|
| 1046 | uint32_t pdb_capabilities(void)
 | 
|---|
| 1047 | {
 | 
|---|
| 1048 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1049 |         return pdb->capabilities(pdb);
 | 
|---|
| 1050 | }
 | 
|---|
| 1051 | 
 | 
|---|
| 1052 | /********************************************************************
 | 
|---|
| 1053 |  Allocate a new RID from the passdb backend.  Verify that it is free
 | 
|---|
| 1054 |  by calling lookup_global_sam_rid() to verify that the RID is not
 | 
|---|
| 1055 |  in use.  This handles servers that have existing users or groups
 | 
|---|
| 1056 |  with add RIDs (assigned from previous algorithmic mappings)
 | 
|---|
| 1057 | ********************************************************************/
 | 
|---|
| 1058 | 
 | 
|---|
| 1059 | bool pdb_new_rid(uint32 *rid)
 | 
|---|
| 1060 | {
 | 
|---|
| 1061 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1062 |         const char *name = NULL;
 | 
|---|
| 1063 |         enum lsa_SidType type;
 | 
|---|
| 1064 |         uint32 allocated_rid = 0;
 | 
|---|
| 1065 |         int i;
 | 
|---|
| 1066 |         TALLOC_CTX *ctx;
 | 
|---|
| 1067 | 
 | 
|---|
| 1068 |         if ((pdb_capabilities() & PDB_CAP_STORE_RIDS) == 0) {
 | 
|---|
| 1069 |                 DEBUG(0, ("Trying to allocate a RID when algorithmic RIDs "
 | 
|---|
| 1070 |                           "are active\n"));
 | 
|---|
| 1071 |                 return False;
 | 
|---|
| 1072 |         }
 | 
|---|
| 1073 | 
 | 
|---|
| 1074 |         if (algorithmic_rid_base() != BASE_RID) {
 | 
|---|
| 1075 |                 DEBUG(0, ("'algorithmic rid base' is set but a passdb backend "
 | 
|---|
| 1076 |                           "without algorithmic RIDs is chosen.\n"));
 | 
|---|
| 1077 |                 DEBUGADD(0, ("Please map all used groups using 'net groupmap "
 | 
|---|
| 1078 |                              "add', set the maximum used RID\n"));
 | 
|---|
| 1079 |                 DEBUGADD(0, ("and remove the parameter\n"));
 | 
|---|
| 1080 |                 return False;
 | 
|---|
| 1081 |         }
 | 
|---|
| 1082 | 
 | 
|---|
| 1083 |         if ( (ctx = talloc_init("pdb_new_rid")) == NULL ) {
 | 
|---|
| 1084 |                 DEBUG(0,("pdb_new_rid: Talloc initialization failure\n"));
 | 
|---|
| 1085 |                 return False;
 | 
|---|
| 1086 |         }
 | 
|---|
| 1087 | 
 | 
|---|
| 1088 |         /* Attempt to get an unused RID (max tires is 250...yes that it is 
 | 
|---|
| 1089 |            and arbitrary number I pulkled out of my head).   -- jerry */
 | 
|---|
| 1090 | 
 | 
|---|
| 1091 |         for ( i=0; allocated_rid==0 && i<250; i++ ) {
 | 
|---|
| 1092 |                 /* get a new RID */
 | 
|---|
| 1093 | 
 | 
|---|
| 1094 |                 if ( !pdb->new_rid(pdb, &allocated_rid) ) {
 | 
|---|
| 1095 |                         return False;
 | 
|---|
| 1096 |                 }
 | 
|---|
| 1097 | 
 | 
|---|
| 1098 |                 /* validate that the RID is not in use */
 | 
|---|
| 1099 | 
 | 
|---|
| 1100 |                 if ( lookup_global_sam_rid( ctx, allocated_rid, &name, &type, NULL ) ) {
 | 
|---|
| 1101 |                         allocated_rid = 0;
 | 
|---|
| 1102 |                 }
 | 
|---|
| 1103 |         }
 | 
|---|
| 1104 | 
 | 
|---|
| 1105 |         TALLOC_FREE( ctx );
 | 
|---|
| 1106 | 
 | 
|---|
| 1107 |         if ( allocated_rid == 0 ) {
 | 
|---|
| 1108 |                 DEBUG(0,("pdb_new_rid: Failed to find unused RID\n"));
 | 
|---|
| 1109 |                 return False;
 | 
|---|
| 1110 |         }
 | 
|---|
| 1111 | 
 | 
|---|
| 1112 |         *rid = allocated_rid;
 | 
|---|
| 1113 | 
 | 
|---|
| 1114 |         return True;
 | 
|---|
| 1115 | }
 | 
|---|
| 1116 | 
 | 
|---|
| 1117 | /***************************************************************
 | 
|---|
| 1118 |   Initialize the static context (at smbd startup etc). 
 | 
|---|
| 1119 | 
 | 
|---|
| 1120 |   If uninitialised, context will auto-init on first use.
 | 
|---|
| 1121 |  ***************************************************************/
 | 
|---|
| 1122 | 
 | 
|---|
| 1123 | bool initialize_password_db(bool reload, struct event_context *event_ctx)
 | 
|---|
| 1124 | {
 | 
|---|
| 1125 |         pdb_event_ctx = event_ctx;
 | 
|---|
| 1126 |         return (pdb_get_methods_reload(reload) != NULL);
 | 
|---|
| 1127 | }
 | 
|---|
| 1128 | 
 | 
|---|
| 1129 | 
 | 
|---|
| 1130 | /***************************************************************************
 | 
|---|
| 1131 |   Default implementations of some functions.
 | 
|---|
| 1132 |  ****************************************************************************/
 | 
|---|
| 1133 | 
 | 
|---|
| 1134 | static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, struct samu *user, const char *sname)
 | 
|---|
| 1135 | {
 | 
|---|
| 1136 |         return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 1137 | }
 | 
|---|
| 1138 | 
 | 
|---|
| 1139 | static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
 | 
|---|
| 1140 | {
 | 
|---|
| 1141 |         return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 1142 | }
 | 
|---|
| 1143 | 
 | 
|---|
| 1144 | static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, struct samu *newpwd)
 | 
|---|
| 1145 | {
 | 
|---|
| 1146 |         return NT_STATUS_NOT_IMPLEMENTED;
 | 
|---|
| 1147 | }
 | 
|---|
| 1148 | 
 | 
|---|
| 1149 | static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, struct samu *newpwd)
 | 
|---|
| 1150 | {
 | 
|---|
| 1151 |         return NT_STATUS_NOT_IMPLEMENTED;
 | 
|---|
| 1152 | }
 | 
|---|
| 1153 | 
 | 
|---|
| 1154 | static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, struct samu *pwd)
 | 
|---|
| 1155 | {
 | 
|---|
| 1156 |         return NT_STATUS_NOT_IMPLEMENTED;
 | 
|---|
| 1157 | }
 | 
|---|
| 1158 | 
 | 
|---|
| 1159 | static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, struct samu *pwd, const char *newname)
 | 
|---|
| 1160 | {
 | 
|---|
| 1161 |         return NT_STATUS_NOT_IMPLEMENTED;
 | 
|---|
| 1162 | }
 | 
|---|
| 1163 | 
 | 
|---|
| 1164 | static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, struct samu *newpwd, bool success)
 | 
|---|
| 1165 | {
 | 
|---|
| 1166 |         /* Only the pdb_nds backend implements this, by
 | 
|---|
| 1167 |          * default just return ok. */
 | 
|---|
| 1168 |         return NT_STATUS_OK;
 | 
|---|
| 1169 | }
 | 
|---|
| 1170 | 
 | 
|---|
| 1171 | static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value)
 | 
|---|
| 1172 | {
 | 
|---|
| 1173 |         return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 | 
|---|
| 1174 | }
 | 
|---|
| 1175 | 
 | 
|---|
| 1176 | static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value)
 | 
|---|
| 1177 | {
 | 
|---|
| 1178 |         return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 | 
|---|
| 1179 | }
 | 
|---|
| 1180 | 
 | 
|---|
| 1181 | static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num)
 | 
|---|
| 1182 | {
 | 
|---|
| 1183 |         *seq_num = time(NULL);
 | 
|---|
| 1184 |         return NT_STATUS_OK;
 | 
|---|
| 1185 | }
 | 
|---|
| 1186 | 
 | 
|---|
| 1187 | static bool pdb_default_uid_to_sid(struct pdb_methods *methods, uid_t uid,
 | 
|---|
| 1188 |                                    DOM_SID *sid)
 | 
|---|
| 1189 | {
 | 
|---|
| 1190 |         struct samu *sampw = NULL;
 | 
|---|
| 1191 |         struct passwd *unix_pw;
 | 
|---|
| 1192 |         bool ret;
 | 
|---|
| 1193 | 
 | 
|---|
| 1194 |         unix_pw = sys_getpwuid( uid );
 | 
|---|
| 1195 | 
 | 
|---|
| 1196 |         if ( !unix_pw ) {
 | 
|---|
| 1197 |                 DEBUG(4,("pdb_default_uid_to_sid: host has no idea of uid "
 | 
|---|
| 1198 |                          "%lu\n", (unsigned long)uid));
 | 
|---|
| 1199 |                 return False;
 | 
|---|
| 1200 |         }
 | 
|---|
| 1201 | 
 | 
|---|
| 1202 |         if ( !(sampw = samu_new( NULL )) ) {
 | 
|---|
| 1203 |                 DEBUG(0,("pdb_default_uid_to_sid: samu_new() failed!\n"));
 | 
|---|
| 1204 |                 return False;
 | 
|---|
| 1205 |         }
 | 
|---|
| 1206 | 
 | 
|---|
| 1207 |         become_root();
 | 
|---|
| 1208 |         ret = NT_STATUS_IS_OK(
 | 
|---|
| 1209 |                 methods->getsampwnam(methods, sampw, unix_pw->pw_name ));
 | 
|---|
| 1210 |         unbecome_root();
 | 
|---|
| 1211 | 
 | 
|---|
| 1212 |         if (!ret) {
 | 
|---|
| 1213 |                 DEBUG(5, ("pdb_default_uid_to_sid: Did not find user "
 | 
|---|
| 1214 |                           "%s (%u)\n", unix_pw->pw_name, (unsigned int)uid));
 | 
|---|
| 1215 |                 TALLOC_FREE(sampw);
 | 
|---|
| 1216 |                 return False;
 | 
|---|
| 1217 |         }
 | 
|---|
| 1218 | 
 | 
|---|
| 1219 |         sid_copy(sid, pdb_get_user_sid(sampw));
 | 
|---|
| 1220 | 
 | 
|---|
| 1221 |         TALLOC_FREE(sampw);
 | 
|---|
| 1222 | 
 | 
|---|
| 1223 |         return True;
 | 
|---|
| 1224 | }
 | 
|---|
| 1225 | 
 | 
|---|
| 1226 | static bool pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid,
 | 
|---|
| 1227 |                                    DOM_SID *sid)
 | 
|---|
| 1228 | {
 | 
|---|
| 1229 |         GROUP_MAP map;
 | 
|---|
| 1230 | 
 | 
|---|
| 1231 |         if (!NT_STATUS_IS_OK(methods->getgrgid(methods, &map, gid))) {
 | 
|---|
| 1232 |                 return False;
 | 
|---|
| 1233 |         }
 | 
|---|
| 1234 | 
 | 
|---|
| 1235 |         sid_copy(sid, &map.sid);
 | 
|---|
| 1236 |         return True;
 | 
|---|
| 1237 | }
 | 
|---|
| 1238 | 
 | 
|---|
| 1239 | static bool pdb_default_sid_to_id(struct pdb_methods *methods,
 | 
|---|
| 1240 |                                   const DOM_SID *sid,
 | 
|---|
| 1241 |                                   union unid_t *id, enum lsa_SidType *type)
 | 
|---|
| 1242 | {
 | 
|---|
| 1243 |         TALLOC_CTX *mem_ctx;
 | 
|---|
| 1244 |         bool ret = False;
 | 
|---|
| 1245 |         const char *name;
 | 
|---|
| 1246 |         uint32 rid;
 | 
|---|
| 1247 | 
 | 
|---|
| 1248 |         mem_ctx = talloc_new(NULL);
 | 
|---|
| 1249 | 
 | 
|---|
| 1250 |         if (mem_ctx == NULL) {
 | 
|---|
| 1251 |                 DEBUG(0, ("talloc_new failed\n"));
 | 
|---|
| 1252 |                 return False;
 | 
|---|
| 1253 |         }
 | 
|---|
| 1254 | 
 | 
|---|
| 1255 |         if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) {
 | 
|---|
| 1256 |                 /* Here we might have users as well as groups and aliases */
 | 
|---|
| 1257 |                 ret = lookup_global_sam_rid(mem_ctx, rid, &name, type, id);
 | 
|---|
| 1258 |                 goto done;
 | 
|---|
| 1259 |         }
 | 
|---|
| 1260 | 
 | 
|---|
| 1261 |         /* check for "Unix User" */
 | 
|---|
| 1262 | 
 | 
|---|
| 1263 |         if ( sid_peek_check_rid(&global_sid_Unix_Users, sid, &rid) ) {
 | 
|---|
| 1264 |                 id->uid = rid;
 | 
|---|
| 1265 |                 *type = SID_NAME_USER;
 | 
|---|
| 1266 |                 ret = True;             
 | 
|---|
| 1267 |                 goto done;              
 | 
|---|
| 1268 |         }
 | 
|---|
| 1269 | 
 | 
|---|
| 1270 |         /* check for "Unix Group" */
 | 
|---|
| 1271 | 
 | 
|---|
| 1272 |         if ( sid_peek_check_rid(&global_sid_Unix_Groups, sid, &rid) ) {
 | 
|---|
| 1273 |                 id->gid = rid;
 | 
|---|
| 1274 |                 *type = SID_NAME_ALIAS;
 | 
|---|
| 1275 |                 ret = True;             
 | 
|---|
| 1276 |                 goto done;              
 | 
|---|
| 1277 |         }
 | 
|---|
| 1278 | 
 | 
|---|
| 1279 |         /* BUILTIN */
 | 
|---|
| 1280 | 
 | 
|---|
| 1281 |         if (sid_check_is_in_builtin(sid) ||
 | 
|---|
| 1282 |             sid_check_is_in_wellknown_domain(sid)) {
 | 
|---|
| 1283 |                 /* Here we only have aliases */
 | 
|---|
| 1284 |                 GROUP_MAP map;
 | 
|---|
| 1285 |                 if (!NT_STATUS_IS_OK(methods->getgrsid(methods, &map, *sid))) {
 | 
|---|
| 1286 |                         DEBUG(10, ("Could not find map for sid %s\n",
 | 
|---|
| 1287 |                                    sid_string_dbg(sid)));
 | 
|---|
| 1288 |                         goto done;
 | 
|---|
| 1289 |                 }
 | 
|---|
| 1290 |                 if ((map.sid_name_use != SID_NAME_ALIAS) &&
 | 
|---|
| 1291 |                     (map.sid_name_use != SID_NAME_WKN_GRP)) {
 | 
|---|
| 1292 |                         DEBUG(10, ("Map for sid %s is a %s, expected an "
 | 
|---|
| 1293 |                                    "alias\n", sid_string_dbg(sid),
 | 
|---|
| 1294 |                                    sid_type_lookup(map.sid_name_use)));
 | 
|---|
| 1295 |                         goto done;
 | 
|---|
| 1296 |                 }
 | 
|---|
| 1297 | 
 | 
|---|
| 1298 |                 id->gid = map.gid;
 | 
|---|
| 1299 |                 *type = SID_NAME_ALIAS;
 | 
|---|
| 1300 |                 ret = True;
 | 
|---|
| 1301 |                 goto done;
 | 
|---|
| 1302 |         }
 | 
|---|
| 1303 | 
 | 
|---|
| 1304 |         DEBUG(5, ("Sid %s is neither ours, a Unix SID, nor builtin\n",
 | 
|---|
| 1305 |                   sid_string_dbg(sid)));
 | 
|---|
| 1306 | 
 | 
|---|
| 1307 |  done:
 | 
|---|
| 1308 | 
 | 
|---|
| 1309 |         TALLOC_FREE(mem_ctx);
 | 
|---|
| 1310 |         return ret;
 | 
|---|
| 1311 | }
 | 
|---|
| 1312 | 
 | 
|---|
| 1313 | static bool get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size_t *p_num)
 | 
|---|
| 1314 | {
 | 
|---|
| 1315 |         struct group *grp;
 | 
|---|
| 1316 |         char **gr;
 | 
|---|
| 1317 |         struct passwd *pwd;
 | 
|---|
| 1318 |         bool winbind_env;
 | 
|---|
| 1319 |         bool ret = False;
 | 
|---|
| 1320 |  
 | 
|---|
| 1321 |         *pp_uids = NULL;
 | 
|---|
| 1322 |         *p_num = 0;
 | 
|---|
| 1323 | 
 | 
|---|
| 1324 |         /* We only look at our own sam, so don't care about imported stuff */
 | 
|---|
| 1325 |         winbind_env = winbind_env_set();
 | 
|---|
| 1326 |         (void)winbind_off();
 | 
|---|
| 1327 | 
 | 
|---|
| 1328 |         if ((grp = getgrgid(gid)) == NULL) {
 | 
|---|
| 1329 |                 /* allow winbindd lookups, but only if they weren't already disabled */
 | 
|---|
| 1330 |                 goto done;
 | 
|---|
| 1331 |         }
 | 
|---|
| 1332 | 
 | 
|---|
| 1333 |         /* Primary group members */
 | 
|---|
| 1334 |         setpwent();
 | 
|---|
| 1335 |         while ((pwd = getpwent()) != NULL) {
 | 
|---|
| 1336 |                 if (pwd->pw_gid == gid) {
 | 
|---|
| 1337 |                         if (!add_uid_to_array_unique(mem_ctx, pwd->pw_uid,
 | 
|---|
| 1338 |                                                 pp_uids, p_num)) {
 | 
|---|
| 1339 |                                 goto done;
 | 
|---|
| 1340 |                         }
 | 
|---|
| 1341 |                 }
 | 
|---|
| 1342 |         }
 | 
|---|
| 1343 |         endpwent();
 | 
|---|
| 1344 | 
 | 
|---|
| 1345 |         /* Secondary group members */
 | 
|---|
| 1346 |         for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
 | 
|---|
| 1347 |                 struct passwd *pw = getpwnam(*gr);
 | 
|---|
| 1348 | 
 | 
|---|
| 1349 |                 if (pw == NULL)
 | 
|---|
| 1350 |                         continue;
 | 
|---|
| 1351 |                 if (!add_uid_to_array_unique(mem_ctx, pw->pw_uid, pp_uids, p_num)) {
 | 
|---|
| 1352 |                         goto done;
 | 
|---|
| 1353 |                 }
 | 
|---|
| 1354 |         }
 | 
|---|
| 1355 | 
 | 
|---|
| 1356 |         ret = True;
 | 
|---|
| 1357 | 
 | 
|---|
| 1358 |   done:
 | 
|---|
| 1359 | 
 | 
|---|
| 1360 |         /* allow winbindd lookups, but only if they weren't already disabled */
 | 
|---|
| 1361 |         if (!winbind_env) {
 | 
|---|
| 1362 |                 (void)winbind_on();
 | 
|---|
| 1363 |         }
 | 
|---|
| 1364 | 
 | 
|---|
| 1365 |         return ret;
 | 
|---|
| 1366 | }
 | 
|---|
| 1367 | 
 | 
|---|
| 1368 | static NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
 | 
|---|
| 1369 |                                                TALLOC_CTX *mem_ctx,
 | 
|---|
| 1370 |                                                const DOM_SID *group,
 | 
|---|
| 1371 |                                                uint32 **pp_member_rids,
 | 
|---|
| 1372 |                                                size_t *p_num_members)
 | 
|---|
| 1373 | {
 | 
|---|
| 1374 |         gid_t gid;
 | 
|---|
| 1375 |         uid_t *uids;
 | 
|---|
| 1376 |         size_t i, num_uids;
 | 
|---|
| 1377 | 
 | 
|---|
| 1378 |         *pp_member_rids = NULL;
 | 
|---|
| 1379 |         *p_num_members = 0;
 | 
|---|
| 1380 | 
 | 
|---|
| 1381 |         if (!sid_to_gid(group, &gid))
 | 
|---|
| 1382 |                 return NT_STATUS_NO_SUCH_GROUP;
 | 
|---|
| 1383 | 
 | 
|---|
| 1384 |         if(!get_memberuids(mem_ctx, gid, &uids, &num_uids))
 | 
|---|
| 1385 |                 return NT_STATUS_NO_SUCH_GROUP;
 | 
|---|
| 1386 | 
 | 
|---|
| 1387 |         if (num_uids == 0)
 | 
|---|
| 1388 |                 return NT_STATUS_OK;
 | 
|---|
| 1389 | 
 | 
|---|
| 1390 |         *pp_member_rids = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_uids);
 | 
|---|
| 1391 | 
 | 
|---|
| 1392 |         for (i=0; i<num_uids; i++) {
 | 
|---|
| 1393 |                 DOM_SID sid;
 | 
|---|
| 1394 | 
 | 
|---|
| 1395 |                 uid_to_sid(&sid, uids[i]);
 | 
|---|
| 1396 | 
 | 
|---|
| 1397 |                 if (!sid_check_is_in_our_domain(&sid)) {
 | 
|---|
| 1398 |                         DEBUG(5, ("Inconsistent SAM -- group member uid not "
 | 
|---|
| 1399 |                                   "in our domain\n"));
 | 
|---|
| 1400 |                         continue;
 | 
|---|
| 1401 |                 }
 | 
|---|
| 1402 | 
 | 
|---|
| 1403 |                 sid_peek_rid(&sid, &(*pp_member_rids)[*p_num_members]);
 | 
|---|
| 1404 |                 *p_num_members += 1;
 | 
|---|
| 1405 |         }
 | 
|---|
| 1406 | 
 | 
|---|
| 1407 |         return NT_STATUS_OK;
 | 
|---|
| 1408 | }
 | 
|---|
| 1409 | 
 | 
|---|
| 1410 | static NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
 | 
|---|
| 1411 |                                                    TALLOC_CTX *mem_ctx,
 | 
|---|
| 1412 |                                                    struct samu *user,
 | 
|---|
| 1413 |                                                    DOM_SID **pp_sids,
 | 
|---|
| 1414 |                                                    gid_t **pp_gids,
 | 
|---|
| 1415 |                                                    size_t *p_num_groups)
 | 
|---|
| 1416 | {
 | 
|---|
| 1417 |         size_t i;
 | 
|---|
| 1418 |         gid_t gid;
 | 
|---|
| 1419 |         struct passwd *pw;
 | 
|---|
| 1420 |         const char *username = pdb_get_username(user);
 | 
|---|
| 1421 | 
 | 
|---|
| 1422 | 
 | 
|---|
| 1423 |         /* Ignore the primary group SID.  Honor the real Unix primary group.
 | 
|---|
| 1424 |            The primary group SID is only of real use to Windows clients */
 | 
|---|
| 1425 | 
 | 
|---|
| 1426 |         if ( !(pw = getpwnam_alloc(mem_ctx, username)) ) {
 | 
|---|
| 1427 |                 return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 1428 |         }
 | 
|---|
| 1429 | 
 | 
|---|
| 1430 |         gid = pw->pw_gid;
 | 
|---|
| 1431 | 
 | 
|---|
| 1432 |         TALLOC_FREE( pw );
 | 
|---|
| 1433 | 
 | 
|---|
| 1434 |         if (!getgroups_unix_user(mem_ctx, username, gid, pp_gids, p_num_groups)) {
 | 
|---|
| 1435 |                 return NT_STATUS_NO_SUCH_USER;
 | 
|---|
| 1436 |         }
 | 
|---|
| 1437 | 
 | 
|---|
| 1438 |         if (*p_num_groups == 0) {
 | 
|---|
| 1439 |                 smb_panic("primary group missing");
 | 
|---|
| 1440 |         }
 | 
|---|
| 1441 | 
 | 
|---|
| 1442 |         *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups);
 | 
|---|
| 1443 | 
 | 
|---|
| 1444 |         if (*pp_sids == NULL) {
 | 
|---|
| 1445 |                 TALLOC_FREE(*pp_gids);
 | 
|---|
| 1446 |                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 1447 |         }
 | 
|---|
| 1448 | 
 | 
|---|
| 1449 |         for (i=0; i<*p_num_groups; i++) {
 | 
|---|
| 1450 |                 gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]);
 | 
|---|
| 1451 |         }
 | 
|---|
| 1452 | 
 | 
|---|
| 1453 |         return NT_STATUS_OK;
 | 
|---|
| 1454 | }
 | 
|---|
| 1455 | 
 | 
|---|
| 1456 | /*******************************************************************
 | 
|---|
| 1457 |  Look up a rid in the SAM we're responsible for (i.e. passdb)
 | 
|---|
| 1458 |  ********************************************************************/
 | 
|---|
| 1459 | 
 | 
|---|
| 1460 | static bool lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
 | 
|---|
| 1461 |                                   const char **name,
 | 
|---|
| 1462 |                                   enum lsa_SidType *psid_name_use,
 | 
|---|
| 1463 |                                   union unid_t *unix_id)
 | 
|---|
| 1464 | {
 | 
|---|
| 1465 |         struct samu *sam_account = NULL;
 | 
|---|
| 1466 |         GROUP_MAP map;
 | 
|---|
| 1467 |         bool ret;
 | 
|---|
| 1468 |         DOM_SID sid;
 | 
|---|
| 1469 | 
 | 
|---|
| 1470 |         *psid_name_use = SID_NAME_UNKNOWN;
 | 
|---|
| 1471 | 
 | 
|---|
| 1472 |         DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
 | 
|---|
| 1473 |                  (unsigned int)rid));
 | 
|---|
| 1474 | 
 | 
|---|
| 1475 |         sid_copy(&sid, get_global_sam_sid());
 | 
|---|
| 1476 |         sid_append_rid(&sid, rid);
 | 
|---|
| 1477 | 
 | 
|---|
| 1478 |         /* see if the passdb can help us with the name of the user */
 | 
|---|
| 1479 | 
 | 
|---|
| 1480 |         if ( !(sam_account = samu_new( NULL )) ) {
 | 
|---|
| 1481 |                 return False;
 | 
|---|
| 1482 |         }
 | 
|---|
| 1483 | 
 | 
|---|
| 1484 |         /* BEING ROOT BLLOCK */
 | 
|---|
| 1485 |         become_root();
 | 
|---|
| 1486 |         if (pdb_getsampwsid(sam_account, &sid)) {
 | 
|---|
| 1487 |                 struct passwd *pw;
 | 
|---|
| 1488 | 
 | 
|---|
| 1489 |                 unbecome_root();                /* -----> EXIT BECOME_ROOT() */
 | 
|---|
| 1490 |                 *name = talloc_strdup(mem_ctx, pdb_get_username(sam_account));
 | 
|---|
| 1491 |                 if (!*name) {
 | 
|---|
| 1492 |                         TALLOC_FREE(sam_account);
 | 
|---|
| 1493 |                         return False;
 | 
|---|
| 1494 |                 }
 | 
|---|
| 1495 | 
 | 
|---|
| 1496 |                 *psid_name_use = SID_NAME_USER;
 | 
|---|
| 1497 | 
 | 
|---|
| 1498 |                 TALLOC_FREE(sam_account);
 | 
|---|
| 1499 | 
 | 
|---|
| 1500 |                 if (unix_id == NULL) {
 | 
|---|
| 1501 |                         return True;
 | 
|---|
| 1502 |                 }
 | 
|---|
| 1503 | 
 | 
|---|
| 1504 |                 pw = Get_Pwnam_alloc(talloc_tos(), *name);
 | 
|---|
| 1505 |                 if (pw == NULL) {
 | 
|---|
| 1506 |                         return False;
 | 
|---|
| 1507 |                 }
 | 
|---|
| 1508 |                 unix_id->uid = pw->pw_uid;
 | 
|---|
| 1509 |                 TALLOC_FREE(pw);
 | 
|---|
| 1510 |                 return True;
 | 
|---|
| 1511 |         }
 | 
|---|
| 1512 |         TALLOC_FREE(sam_account);
 | 
|---|
| 1513 | 
 | 
|---|
| 1514 |         ret = pdb_getgrsid(&map, sid);
 | 
|---|
| 1515 |         unbecome_root();
 | 
|---|
| 1516 |         /* END BECOME_ROOT BLOCK */
 | 
|---|
| 1517 | 
 | 
|---|
| 1518 |         /* do not resolve SIDs to a name unless there is a valid 
 | 
|---|
| 1519 |            gid associated with it */
 | 
|---|
| 1520 | 
 | 
|---|
| 1521 |         if ( ret && (map.gid != (gid_t)-1) ) {
 | 
|---|
| 1522 |                 *name = talloc_strdup(mem_ctx, map.nt_name);
 | 
|---|
| 1523 |                 *psid_name_use = map.sid_name_use;
 | 
|---|
| 1524 | 
 | 
|---|
| 1525 |                 if ( unix_id ) {
 | 
|---|
| 1526 |                         unix_id->gid = map.gid;
 | 
|---|
| 1527 |                 }
 | 
|---|
| 1528 | 
 | 
|---|
| 1529 |                 return True;
 | 
|---|
| 1530 |         }
 | 
|---|
| 1531 | 
 | 
|---|
| 1532 |         /* Windows will always map RID 513 to something.  On a non-domain 
 | 
|---|
| 1533 |            controller, this gets mapped to SERVER\None. */
 | 
|---|
| 1534 | 
 | 
|---|
| 1535 |         if ( unix_id ) {
 | 
|---|
| 1536 |                 DEBUG(5, ("Can't find a unix id for an unmapped group\n"));
 | 
|---|
| 1537 |                 return False;
 | 
|---|
| 1538 |         }
 | 
|---|
| 1539 | 
 | 
|---|
| 1540 |         if ( rid == DOMAIN_GROUP_RID_USERS ) {
 | 
|---|
| 1541 |                 *name = talloc_strdup(mem_ctx, "None" );
 | 
|---|
| 1542 |                 *psid_name_use = SID_NAME_DOM_GRP;
 | 
|---|
| 1543 | 
 | 
|---|
| 1544 |                 return True;
 | 
|---|
| 1545 |         }
 | 
|---|
| 1546 | 
 | 
|---|
| 1547 |         return False;
 | 
|---|
| 1548 | }
 | 
|---|
| 1549 | 
 | 
|---|
| 1550 | static NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
 | 
|---|
| 1551 |                                         const DOM_SID *domain_sid,
 | 
|---|
| 1552 |                                         int num_rids,
 | 
|---|
| 1553 |                                         uint32 *rids,
 | 
|---|
| 1554 |                                         const char **names,
 | 
|---|
| 1555 |                                         enum lsa_SidType *attrs)
 | 
|---|
| 1556 | {
 | 
|---|
| 1557 |         int i;
 | 
|---|
| 1558 |         NTSTATUS result;
 | 
|---|
| 1559 |         bool have_mapped = False;
 | 
|---|
| 1560 |         bool have_unmapped = False;
 | 
|---|
| 1561 | 
 | 
|---|
| 1562 |         if (sid_check_is_builtin(domain_sid)) {
 | 
|---|
| 1563 | 
 | 
|---|
| 1564 |                 for (i=0; i<num_rids; i++) {
 | 
|---|
| 1565 |                         const char *name;
 | 
|---|
| 1566 | 
 | 
|---|
| 1567 |                         if (lookup_builtin_rid(names, rids[i], &name)) {
 | 
|---|
| 1568 |                                 attrs[i] = SID_NAME_ALIAS;
 | 
|---|
| 1569 |                                 names[i] = name;
 | 
|---|
| 1570 |                                 DEBUG(5,("lookup_rids: %s:%d\n",
 | 
|---|
| 1571 |                                          names[i], attrs[i]));
 | 
|---|
| 1572 |                                 have_mapped = True;
 | 
|---|
| 1573 |                         } else {
 | 
|---|
| 1574 |                                 have_unmapped = True;
 | 
|---|
| 1575 |                                 attrs[i] = SID_NAME_UNKNOWN;
 | 
|---|
| 1576 |                         }
 | 
|---|
| 1577 |                 }
 | 
|---|
| 1578 |                 goto done;
 | 
|---|
| 1579 |         }
 | 
|---|
| 1580 | 
 | 
|---|
| 1581 |         /* Should not happen, but better check once too many */
 | 
|---|
| 1582 |         if (!sid_check_is_domain(domain_sid)) {
 | 
|---|
| 1583 |                 return NT_STATUS_INVALID_HANDLE;
 | 
|---|
| 1584 |         }
 | 
|---|
| 1585 | 
 | 
|---|
| 1586 |         for (i = 0; i < num_rids; i++) {
 | 
|---|
| 1587 |                 const char *name;
 | 
|---|
| 1588 | 
 | 
|---|
| 1589 |                 if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i],
 | 
|---|
| 1590 |                                           NULL)) {
 | 
|---|
| 1591 |                         if (name == NULL) {
 | 
|---|
| 1592 |                                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 1593 |                         }
 | 
|---|
| 1594 |                         names[i] = name;
 | 
|---|
| 1595 |                         DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
 | 
|---|
| 1596 |                         have_mapped = True;
 | 
|---|
| 1597 |                 } else {
 | 
|---|
| 1598 |                         have_unmapped = True;
 | 
|---|
| 1599 |                         attrs[i] = SID_NAME_UNKNOWN;
 | 
|---|
| 1600 |                 }
 | 
|---|
| 1601 |         }
 | 
|---|
| 1602 | 
 | 
|---|
| 1603 |  done:
 | 
|---|
| 1604 | 
 | 
|---|
| 1605 |         result = NT_STATUS_NONE_MAPPED;
 | 
|---|
| 1606 | 
 | 
|---|
| 1607 |         if (have_mapped)
 | 
|---|
| 1608 |                 result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
 | 
|---|
| 1609 | 
 | 
|---|
| 1610 |         return result;
 | 
|---|
| 1611 | }
 | 
|---|
| 1612 | 
 | 
|---|
| 1613 | #if 0
 | 
|---|
| 1614 | static NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
 | 
|---|
| 1615 |                                          const DOM_SID *domain_sid,
 | 
|---|
| 1616 |                                          int num_names,
 | 
|---|
| 1617 |                                          const char **names,
 | 
|---|
| 1618 |                                          uint32 *rids,
 | 
|---|
| 1619 |                                          enum lsa_SidType *attrs)
 | 
|---|
| 1620 | {
 | 
|---|
| 1621 |         int i;
 | 
|---|
| 1622 |         NTSTATUS result;
 | 
|---|
| 1623 |         bool have_mapped = False;
 | 
|---|
| 1624 |         bool have_unmapped = False;
 | 
|---|
| 1625 | 
 | 
|---|
| 1626 |         if (sid_check_is_builtin(domain_sid)) {
 | 
|---|
| 1627 | 
 | 
|---|
| 1628 |                 for (i=0; i<num_names; i++) {
 | 
|---|
| 1629 |                         uint32 rid;
 | 
|---|
| 1630 | 
 | 
|---|
| 1631 |                         if (lookup_builtin_name(names[i], &rid)) {
 | 
|---|
| 1632 |                                 attrs[i] = SID_NAME_ALIAS;
 | 
|---|
| 1633 |                                 rids[i] = rid;
 | 
|---|
| 1634 |                                 DEBUG(5,("lookup_rids: %s:%d\n",
 | 
|---|
| 1635 |                                          names[i], attrs[i]));
 | 
|---|
| 1636 |                                 have_mapped = True;
 | 
|---|
| 1637 |                         } else {
 | 
|---|
| 1638 |                                 have_unmapped = True;
 | 
|---|
| 1639 |                                 attrs[i] = SID_NAME_UNKNOWN;
 | 
|---|
| 1640 |                         }
 | 
|---|
| 1641 |                 }
 | 
|---|
| 1642 |                 goto done;
 | 
|---|
| 1643 |         }
 | 
|---|
| 1644 | 
 | 
|---|
| 1645 |         /* Should not happen, but better check once too many */
 | 
|---|
| 1646 |         if (!sid_check_is_domain(domain_sid)) {
 | 
|---|
| 1647 |                 return NT_STATUS_INVALID_HANDLE;
 | 
|---|
| 1648 |         }
 | 
|---|
| 1649 | 
 | 
|---|
| 1650 |         for (i = 0; i < num_names; i++) {
 | 
|---|
| 1651 |                 if (lookup_global_sam_name(names[i], 0, &rids[i], &attrs[i])) {
 | 
|---|
| 1652 |                         DEBUG(5,("lookup_names: %s-> %d:%d\n", names[i],
 | 
|---|
| 1653 |                                  rids[i], attrs[i]));
 | 
|---|
| 1654 |                         have_mapped = True;
 | 
|---|
| 1655 |                 } else {
 | 
|---|
| 1656 |                         have_unmapped = True;
 | 
|---|
| 1657 |                         attrs[i] = SID_NAME_UNKNOWN;
 | 
|---|
| 1658 |                 }
 | 
|---|
| 1659 |         }
 | 
|---|
| 1660 | 
 | 
|---|
| 1661 |  done:
 | 
|---|
| 1662 | 
 | 
|---|
| 1663 |         result = NT_STATUS_NONE_MAPPED;
 | 
|---|
| 1664 | 
 | 
|---|
| 1665 |         if (have_mapped)
 | 
|---|
| 1666 |                 result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
 | 
|---|
| 1667 | 
 | 
|---|
| 1668 |         return result;
 | 
|---|
| 1669 | }
 | 
|---|
| 1670 | #endif
 | 
|---|
| 1671 | 
 | 
|---|
| 1672 | static int pdb_search_destructor(struct pdb_search *search)
 | 
|---|
| 1673 | {
 | 
|---|
| 1674 |         if ((!search->search_ended) && (search->search_end != NULL)) {
 | 
|---|
| 1675 |                 search->search_end(search);
 | 
|---|
| 1676 |         }
 | 
|---|
| 1677 |         return 0;
 | 
|---|
| 1678 | }
 | 
|---|
| 1679 | 
 | 
|---|
| 1680 | struct pdb_search *pdb_search_init(TALLOC_CTX *mem_ctx,
 | 
|---|
| 1681 |                                    enum pdb_search_type type)
 | 
|---|
| 1682 | {
 | 
|---|
| 1683 |         struct pdb_search *result;
 | 
|---|
| 1684 | 
 | 
|---|
| 1685 |         result = talloc(mem_ctx, struct pdb_search);
 | 
|---|
| 1686 |         if (result == NULL) {
 | 
|---|
| 1687 |                 DEBUG(0, ("talloc failed\n"));
 | 
|---|
| 1688 |                 return NULL;
 | 
|---|
| 1689 |         }
 | 
|---|
| 1690 | 
 | 
|---|
| 1691 |         result->type = type;
 | 
|---|
| 1692 |         result->cache = NULL;
 | 
|---|
| 1693 |         result->num_entries = 0;
 | 
|---|
| 1694 |         result->cache_size = 0;
 | 
|---|
| 1695 |         result->search_ended = False;
 | 
|---|
| 1696 |         result->search_end = NULL;
 | 
|---|
| 1697 | 
 | 
|---|
| 1698 |         /* Segfault appropriately if not initialized */
 | 
|---|
| 1699 |         result->next_entry = NULL;
 | 
|---|
| 1700 |         result->search_end = NULL;
 | 
|---|
| 1701 | 
 | 
|---|
| 1702 |         talloc_set_destructor(result, pdb_search_destructor);
 | 
|---|
| 1703 | 
 | 
|---|
| 1704 |         return result;
 | 
|---|
| 1705 | }
 | 
|---|
| 1706 | 
 | 
|---|
| 1707 | static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
 | 
|---|
| 1708 |                               uint16 acct_flags,
 | 
|---|
| 1709 |                               const char *account_name,
 | 
|---|
| 1710 |                               const char *fullname,
 | 
|---|
| 1711 |                               const char *description,
 | 
|---|
| 1712 |                               struct samr_displayentry *entry)
 | 
|---|
| 1713 | {
 | 
|---|
| 1714 |         entry->rid = rid;
 | 
|---|
| 1715 |         entry->acct_flags = acct_flags;
 | 
|---|
| 1716 | 
 | 
|---|
| 1717 |         if (account_name != NULL)
 | 
|---|
| 1718 |                 entry->account_name = talloc_strdup(mem_ctx, account_name);
 | 
|---|
| 1719 |         else
 | 
|---|
| 1720 |                 entry->account_name = "";
 | 
|---|
| 1721 | 
 | 
|---|
| 1722 |         if (fullname != NULL)
 | 
|---|
| 1723 |                 entry->fullname = talloc_strdup(mem_ctx, fullname);
 | 
|---|
| 1724 |         else
 | 
|---|
| 1725 |                 entry->fullname = "";
 | 
|---|
| 1726 | 
 | 
|---|
| 1727 |         if (description != NULL)
 | 
|---|
| 1728 |                 entry->description = talloc_strdup(mem_ctx, description);
 | 
|---|
| 1729 |         else
 | 
|---|
| 1730 |                 entry->description = "";
 | 
|---|
| 1731 | }
 | 
|---|
| 1732 | 
 | 
|---|
| 1733 | struct group_search {
 | 
|---|
| 1734 |         GROUP_MAP *groups;
 | 
|---|
| 1735 |         size_t num_groups, current_group;
 | 
|---|
| 1736 | };
 | 
|---|
| 1737 | 
 | 
|---|
| 1738 | static bool next_entry_groups(struct pdb_search *s,
 | 
|---|
| 1739 |                               struct samr_displayentry *entry)
 | 
|---|
| 1740 | {
 | 
|---|
| 1741 |         struct group_search *state = (struct group_search *)s->private_data;
 | 
|---|
| 1742 |         uint32 rid;
 | 
|---|
| 1743 |         GROUP_MAP *map = &state->groups[state->current_group];
 | 
|---|
| 1744 | 
 | 
|---|
| 1745 |         if (state->current_group == state->num_groups)
 | 
|---|
| 1746 |                 return False;
 | 
|---|
| 1747 | 
 | 
|---|
| 1748 |         sid_peek_rid(&map->sid, &rid);
 | 
|---|
| 1749 | 
 | 
|---|
| 1750 |         fill_displayentry(s, rid, 0, map->nt_name, NULL, map->comment, entry);
 | 
|---|
| 1751 | 
 | 
|---|
| 1752 |         state->current_group += 1;
 | 
|---|
| 1753 |         return True;
 | 
|---|
| 1754 | }
 | 
|---|
| 1755 | 
 | 
|---|
| 1756 | static void search_end_groups(struct pdb_search *search)
 | 
|---|
| 1757 | {
 | 
|---|
| 1758 |         struct group_search *state =
 | 
|---|
| 1759 |                 (struct group_search *)search->private_data;
 | 
|---|
| 1760 |         SAFE_FREE(state->groups);
 | 
|---|
| 1761 | }
 | 
|---|
| 1762 | 
 | 
|---|
| 1763 | static bool pdb_search_grouptype(struct pdb_search *search,
 | 
|---|
| 1764 |                                  const DOM_SID *sid, enum lsa_SidType type)
 | 
|---|
| 1765 | {
 | 
|---|
| 1766 |         struct group_search *state;
 | 
|---|
| 1767 | 
 | 
|---|
| 1768 |         state = talloc(search, struct group_search);
 | 
|---|
| 1769 |         if (state == NULL) {
 | 
|---|
| 1770 |                 DEBUG(0, ("talloc failed\n"));
 | 
|---|
| 1771 |                 return False;
 | 
|---|
| 1772 |         }
 | 
|---|
| 1773 | 
 | 
|---|
| 1774 |         if (!pdb_enum_group_mapping(sid, type, &state->groups, &state->num_groups,
 | 
|---|
| 1775 |                                     True)) {
 | 
|---|
| 1776 |                 DEBUG(0, ("Could not enum groups\n"));
 | 
|---|
| 1777 |                 return False;
 | 
|---|
| 1778 |         }
 | 
|---|
| 1779 | 
 | 
|---|
| 1780 |         state->current_group = 0;
 | 
|---|
| 1781 |         search->private_data = state;
 | 
|---|
| 1782 |         search->next_entry = next_entry_groups;
 | 
|---|
| 1783 |         search->search_end = search_end_groups;
 | 
|---|
| 1784 |         return True;
 | 
|---|
| 1785 | }
 | 
|---|
| 1786 | 
 | 
|---|
| 1787 | static bool pdb_default_search_groups(struct pdb_methods *methods,
 | 
|---|
| 1788 |                                       struct pdb_search *search)
 | 
|---|
| 1789 | {
 | 
|---|
| 1790 |         return pdb_search_grouptype(search, get_global_sam_sid(), SID_NAME_DOM_GRP);
 | 
|---|
| 1791 | }
 | 
|---|
| 1792 | 
 | 
|---|
| 1793 | static bool pdb_default_search_aliases(struct pdb_methods *methods,
 | 
|---|
| 1794 |                                        struct pdb_search *search,
 | 
|---|
| 1795 |                                        const DOM_SID *sid)
 | 
|---|
| 1796 | {
 | 
|---|
| 1797 | 
 | 
|---|
| 1798 |         return pdb_search_grouptype(search, sid, SID_NAME_ALIAS);
 | 
|---|
| 1799 | }
 | 
|---|
| 1800 | 
 | 
|---|
| 1801 | static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
 | 
|---|
| 1802 |                                                      uint32 idx)
 | 
|---|
| 1803 | {
 | 
|---|
| 1804 |         if (idx < search->num_entries)
 | 
|---|
| 1805 |                 return &search->cache[idx];
 | 
|---|
| 1806 | 
 | 
|---|
| 1807 |         if (search->search_ended)
 | 
|---|
| 1808 |                 return NULL;
 | 
|---|
| 1809 | 
 | 
|---|
| 1810 |         while (idx >= search->num_entries) {
 | 
|---|
| 1811 |                 struct samr_displayentry entry;
 | 
|---|
| 1812 | 
 | 
|---|
| 1813 |                 if (!search->next_entry(search, &entry)) {
 | 
|---|
| 1814 |                         search->search_end(search);
 | 
|---|
| 1815 |                         search->search_ended = True;
 | 
|---|
| 1816 |                         break;
 | 
|---|
| 1817 |                 }
 | 
|---|
| 1818 | 
 | 
|---|
| 1819 |                 ADD_TO_LARGE_ARRAY(search, struct samr_displayentry,
 | 
|---|
| 1820 |                                    entry, &search->cache, &search->num_entries,
 | 
|---|
| 1821 |                                    &search->cache_size);
 | 
|---|
| 1822 |         }
 | 
|---|
| 1823 | 
 | 
|---|
| 1824 |         return (search->num_entries > idx) ? &search->cache[idx] : NULL;
 | 
|---|
| 1825 | }
 | 
|---|
| 1826 | 
 | 
|---|
| 1827 | struct pdb_search *pdb_search_users(TALLOC_CTX *mem_ctx, uint32 acct_flags)
 | 
|---|
| 1828 | {
 | 
|---|
| 1829 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1830 |         struct pdb_search *result;
 | 
|---|
| 1831 | 
 | 
|---|
| 1832 |         result = pdb_search_init(mem_ctx, PDB_USER_SEARCH);
 | 
|---|
| 1833 |         if (result == NULL) {
 | 
|---|
| 1834 |                 return NULL;
 | 
|---|
| 1835 |         }
 | 
|---|
| 1836 | 
 | 
|---|
| 1837 |         if (!pdb->search_users(pdb, result, acct_flags)) {
 | 
|---|
| 1838 |                 TALLOC_FREE(result);
 | 
|---|
| 1839 |                 return NULL;
 | 
|---|
| 1840 |         }
 | 
|---|
| 1841 |         return result;
 | 
|---|
| 1842 | }
 | 
|---|
| 1843 | 
 | 
|---|
| 1844 | struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx)
 | 
|---|
| 1845 | {
 | 
|---|
| 1846 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1847 |         struct pdb_search *result;
 | 
|---|
| 1848 | 
 | 
|---|
| 1849 |         result = pdb_search_init(mem_ctx, PDB_GROUP_SEARCH);
 | 
|---|
| 1850 |         if (result == NULL) {
 | 
|---|
| 1851 |                  return NULL;
 | 
|---|
| 1852 |         }
 | 
|---|
| 1853 | 
 | 
|---|
| 1854 |         if (!pdb->search_groups(pdb, result)) {
 | 
|---|
| 1855 |                 TALLOC_FREE(result);
 | 
|---|
| 1856 |                 return NULL;
 | 
|---|
| 1857 |         }
 | 
|---|
| 1858 |         return result;
 | 
|---|
| 1859 | }
 | 
|---|
| 1860 | 
 | 
|---|
| 1861 | struct pdb_search *pdb_search_aliases(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
 | 
|---|
| 1862 | {
 | 
|---|
| 1863 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1864 |         struct pdb_search *result;
 | 
|---|
| 1865 | 
 | 
|---|
| 1866 |         if (pdb == NULL) return NULL;
 | 
|---|
| 1867 | 
 | 
|---|
| 1868 |         result = pdb_search_init(mem_ctx, PDB_ALIAS_SEARCH);
 | 
|---|
| 1869 |         if (result == NULL) {
 | 
|---|
| 1870 |                 return NULL;
 | 
|---|
| 1871 |         }
 | 
|---|
| 1872 | 
 | 
|---|
| 1873 |         if (!pdb->search_aliases(pdb, result, sid)) {
 | 
|---|
| 1874 |                 TALLOC_FREE(result);
 | 
|---|
| 1875 |                 return NULL;
 | 
|---|
| 1876 |         }
 | 
|---|
| 1877 |         return result;
 | 
|---|
| 1878 | }
 | 
|---|
| 1879 | 
 | 
|---|
| 1880 | uint32 pdb_search_entries(struct pdb_search *search,
 | 
|---|
| 1881 |                           uint32 start_idx, uint32 max_entries,
 | 
|---|
| 1882 |                           struct samr_displayentry **result)
 | 
|---|
| 1883 | {
 | 
|---|
| 1884 |         struct samr_displayentry *end_entry;
 | 
|---|
| 1885 |         uint32 end_idx = start_idx+max_entries-1;
 | 
|---|
| 1886 | 
 | 
|---|
| 1887 |         /* The first entry needs to be searched after the last. Otherwise the
 | 
|---|
| 1888 |          * first entry might have moved due to a realloc during the search for
 | 
|---|
| 1889 |          * the last entry. */
 | 
|---|
| 1890 | 
 | 
|---|
| 1891 |         end_entry = pdb_search_getentry(search, end_idx);
 | 
|---|
| 1892 |         *result = pdb_search_getentry(search, start_idx);
 | 
|---|
| 1893 | 
 | 
|---|
| 1894 |         if (end_entry != NULL)
 | 
|---|
| 1895 |                 return max_entries;
 | 
|---|
| 1896 | 
 | 
|---|
| 1897 |         if (start_idx >= search->num_entries)
 | 
|---|
| 1898 |                 return 0;
 | 
|---|
| 1899 | 
 | 
|---|
| 1900 |         return search->num_entries - start_idx;
 | 
|---|
| 1901 | }
 | 
|---|
| 1902 | 
 | 
|---|
| 1903 | /*******************************************************************
 | 
|---|
| 1904 |  trustdom methods
 | 
|---|
| 1905 |  *******************************************************************/
 | 
|---|
| 1906 | 
 | 
|---|
| 1907 | bool pdb_get_trusteddom_pw(const char *domain, char** pwd, DOM_SID *sid, 
 | 
|---|
| 1908 |                            time_t *pass_last_set_time)
 | 
|---|
| 1909 | {
 | 
|---|
| 1910 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1911 |         return pdb->get_trusteddom_pw(pdb, domain, pwd, sid, 
 | 
|---|
| 1912 |                         pass_last_set_time);
 | 
|---|
| 1913 | }
 | 
|---|
| 1914 | 
 | 
|---|
| 1915 | bool pdb_set_trusteddom_pw(const char* domain, const char* pwd,
 | 
|---|
| 1916 |                            const DOM_SID *sid)
 | 
|---|
| 1917 | {
 | 
|---|
| 1918 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1919 |         return pdb->set_trusteddom_pw(pdb, domain, pwd, sid);
 | 
|---|
| 1920 | }
 | 
|---|
| 1921 | 
 | 
|---|
| 1922 | bool pdb_del_trusteddom_pw(const char *domain)
 | 
|---|
| 1923 | {
 | 
|---|
| 1924 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1925 |         return pdb->del_trusteddom_pw(pdb, domain);
 | 
|---|
| 1926 | }
 | 
|---|
| 1927 | 
 | 
|---|
| 1928 | NTSTATUS pdb_enum_trusteddoms(TALLOC_CTX *mem_ctx, uint32 *num_domains,
 | 
|---|
| 1929 |                               struct trustdom_info ***domains)
 | 
|---|
| 1930 | {
 | 
|---|
| 1931 |         struct pdb_methods *pdb = pdb_get_methods();
 | 
|---|
| 1932 |         return pdb->enum_trusteddoms(pdb, mem_ctx, num_domains, domains);
 | 
|---|
| 1933 | }
 | 
|---|
| 1934 | 
 | 
|---|
| 1935 | /*******************************************************************
 | 
|---|
| 1936 |  the defaults for trustdom methods: 
 | 
|---|
| 1937 |  these simply call the original passdb/secrets.c actions,
 | 
|---|
| 1938 |  to be replaced by pdb_ldap.
 | 
|---|
| 1939 |  *******************************************************************/
 | 
|---|
| 1940 | 
 | 
|---|
| 1941 | static bool pdb_default_get_trusteddom_pw(struct pdb_methods *methods,
 | 
|---|
| 1942 |                                           const char *domain, 
 | 
|---|
| 1943 |                                           char** pwd, 
 | 
|---|
| 1944 |                                           DOM_SID *sid, 
 | 
|---|
| 1945 |                                           time_t *pass_last_set_time)
 | 
|---|
| 1946 | {
 | 
|---|
| 1947 |         return secrets_fetch_trusted_domain_password(domain, pwd,
 | 
|---|
| 1948 |                                 sid, pass_last_set_time);
 | 
|---|
| 1949 | 
 | 
|---|
| 1950 | }
 | 
|---|
| 1951 | 
 | 
|---|
| 1952 | static bool pdb_default_set_trusteddom_pw(struct pdb_methods *methods, 
 | 
|---|
| 1953 |                                           const char* domain, 
 | 
|---|
| 1954 |                                           const char* pwd,
 | 
|---|
| 1955 |                                           const DOM_SID *sid)
 | 
|---|
| 1956 | {
 | 
|---|
| 1957 |         return secrets_store_trusted_domain_password(domain, pwd, sid);
 | 
|---|
| 1958 | }
 | 
|---|
| 1959 | 
 | 
|---|
| 1960 | static bool pdb_default_del_trusteddom_pw(struct pdb_methods *methods, 
 | 
|---|
| 1961 |                                           const char *domain)
 | 
|---|
| 1962 | {
 | 
|---|
| 1963 |         return trusted_domain_password_delete(domain);
 | 
|---|
| 1964 | }
 | 
|---|
| 1965 | 
 | 
|---|
| 1966 | static NTSTATUS pdb_default_enum_trusteddoms(struct pdb_methods *methods,
 | 
|---|
| 1967 |                                              TALLOC_CTX *mem_ctx, 
 | 
|---|
| 1968 |                                              uint32 *num_domains,
 | 
|---|
| 1969 |                                              struct trustdom_info ***domains)
 | 
|---|
| 1970 | {
 | 
|---|
| 1971 |         return secrets_trusted_domains(mem_ctx, num_domains, domains);
 | 
|---|
| 1972 | }
 | 
|---|
| 1973 | 
 | 
|---|
| 1974 | static struct pdb_domain_info *pdb_default_get_domain_info(
 | 
|---|
| 1975 |         struct pdb_methods *m, TALLOC_CTX *mem_ctx)
 | 
|---|
| 1976 | {
 | 
|---|
| 1977 |         return NULL;
 | 
|---|
| 1978 | }
 | 
|---|
| 1979 | 
 | 
|---|
| 1980 | /*******************************************************************
 | 
|---|
| 1981 |  Create a pdb_methods structure and initialize it with the default
 | 
|---|
| 1982 |  operations.  In this way a passdb module can simply implement
 | 
|---|
| 1983 |  the functionality it cares about.  However, normally this is done 
 | 
|---|
| 1984 |  in groups of related functions.
 | 
|---|
| 1985 | *******************************************************************/
 | 
|---|
| 1986 | 
 | 
|---|
| 1987 | NTSTATUS make_pdb_method( struct pdb_methods **methods ) 
 | 
|---|
| 1988 | {
 | 
|---|
| 1989 |         /* allocate memory for the structure as its own talloc CTX */
 | 
|---|
| 1990 | 
 | 
|---|
| 1991 |         *methods = talloc_zero(talloc_autofree_context(), struct pdb_methods);
 | 
|---|
| 1992 |         if (*methods == NULL) {
 | 
|---|
| 1993 |                 return NT_STATUS_NO_MEMORY;
 | 
|---|
| 1994 |         }
 | 
|---|
| 1995 | 
 | 
|---|
| 1996 |         (*methods)->get_domain_info = pdb_default_get_domain_info;
 | 
|---|
| 1997 |         (*methods)->getsampwnam = pdb_default_getsampwnam;
 | 
|---|
| 1998 |         (*methods)->getsampwsid = pdb_default_getsampwsid;
 | 
|---|
| 1999 |         (*methods)->create_user = pdb_default_create_user;
 | 
|---|
| 2000 |         (*methods)->delete_user = pdb_default_delete_user;
 | 
|---|
| 2001 |         (*methods)->add_sam_account = pdb_default_add_sam_account;
 | 
|---|
| 2002 |         (*methods)->update_sam_account = pdb_default_update_sam_account;
 | 
|---|
| 2003 |         (*methods)->delete_sam_account = pdb_default_delete_sam_account;
 | 
|---|
| 2004 |         (*methods)->rename_sam_account = pdb_default_rename_sam_account;
 | 
|---|
| 2005 |         (*methods)->update_login_attempts = pdb_default_update_login_attempts;
 | 
|---|
| 2006 | 
 | 
|---|
| 2007 |         (*methods)->getgrsid = pdb_default_getgrsid;
 | 
|---|
| 2008 |         (*methods)->getgrgid = pdb_default_getgrgid;
 | 
|---|
| 2009 |         (*methods)->getgrnam = pdb_default_getgrnam;
 | 
|---|
| 2010 |         (*methods)->create_dom_group = pdb_default_create_dom_group;
 | 
|---|
| 2011 |         (*methods)->delete_dom_group = pdb_default_delete_dom_group;
 | 
|---|
| 2012 |         (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
 | 
|---|
| 2013 |         (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
 | 
|---|
| 2014 |         (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
 | 
|---|
| 2015 |         (*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
 | 
|---|
| 2016 |         (*methods)->enum_group_members = pdb_default_enum_group_members;
 | 
|---|
| 2017 |         (*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
 | 
|---|
| 2018 |         (*methods)->set_unix_primary_group = pdb_default_set_unix_primary_group;
 | 
|---|
| 2019 |         (*methods)->add_groupmem = pdb_default_add_groupmem;
 | 
|---|
| 2020 |         (*methods)->del_groupmem = pdb_default_del_groupmem;
 | 
|---|
| 2021 |         (*methods)->create_alias = pdb_default_create_alias;
 | 
|---|
| 2022 |         (*methods)->delete_alias = pdb_default_delete_alias;
 | 
|---|
| 2023 |         (*methods)->get_aliasinfo = pdb_default_get_aliasinfo;
 | 
|---|
| 2024 |         (*methods)->set_aliasinfo = pdb_default_set_aliasinfo;
 | 
|---|
| 2025 |         (*methods)->add_aliasmem = pdb_default_add_aliasmem;
 | 
|---|
| 2026 |         (*methods)->del_aliasmem = pdb_default_del_aliasmem;
 | 
|---|
| 2027 |         (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
 | 
|---|
| 2028 |         (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
 | 
|---|
| 2029 |         (*methods)->lookup_rids = pdb_default_lookup_rids;
 | 
|---|
| 2030 |         (*methods)->get_account_policy = pdb_default_get_account_policy;
 | 
|---|
| 2031 |         (*methods)->set_account_policy = pdb_default_set_account_policy;
 | 
|---|
| 2032 |         (*methods)->get_seq_num = pdb_default_get_seq_num;
 | 
|---|
| 2033 |         (*methods)->uid_to_sid = pdb_default_uid_to_sid;
 | 
|---|
| 2034 |         (*methods)->gid_to_sid = pdb_default_gid_to_sid;
 | 
|---|
| 2035 |         (*methods)->sid_to_id = pdb_default_sid_to_id;
 | 
|---|
| 2036 | 
 | 
|---|
| 2037 |         (*methods)->search_groups = pdb_default_search_groups;
 | 
|---|
| 2038 |         (*methods)->search_aliases = pdb_default_search_aliases;
 | 
|---|
| 2039 | 
 | 
|---|
| 2040 |         (*methods)->get_trusteddom_pw = pdb_default_get_trusteddom_pw;
 | 
|---|
| 2041 |         (*methods)->set_trusteddom_pw = pdb_default_set_trusteddom_pw;
 | 
|---|
| 2042 |         (*methods)->del_trusteddom_pw = pdb_default_del_trusteddom_pw;
 | 
|---|
| 2043 |         (*methods)->enum_trusteddoms  = pdb_default_enum_trusteddoms;
 | 
|---|
| 2044 | 
 | 
|---|
| 2045 |         return NT_STATUS_OK;
 | 
|---|
| 2046 | }
 | 
|---|