static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag) { struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; TDB_CONTEXT *pwd_tdb = NULL; TDB_DATA key, data; uint8 *buf = NULL; fstring keystr; fstring name; BOOL ret = True; uint32 user_rid; /* invalidate the existing TDB iterator if it is open */ if (tdb_state->passwd_tdb) { tdb_close(tdb_state->passwd_tdb); tdb_state->passwd_tdb = NULL; } /* open the account TDB passwd*/ pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600); if (!pwd_tdb) { DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location)); return False; } if (!pdb_get_group_rid(newpwd)) { DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n", pdb_get_username(newpwd))); ret = False; goto done; } if ( !(user_rid = pdb_get_user_rid(newpwd)) ) { DEBUG(0,("tdb_update_sam: SAM_ACCOUNT (%s) with no RID!\n", pdb_get_username(newpwd))); ret = False; goto done; } /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */ if ((data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1) { DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n")); ret = False; goto done; } data.dptr = (char *)buf; fstrcpy(name, pdb_get_username(newpwd)); strlower_m(name); DEBUG(5, ("Storing %saccount %s with RID %d\n", flag == TDB_INSERT ? "(new) " : "", name, user_rid)); /* setup the USER index key */ slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); key.dptr = keystr; key.dsize = strlen(keystr) + 1; /* add the account */ if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) { DEBUG(0, ("Unable to modify passwd TDB!")); DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb))); DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr)); ret = False; goto done; } /* setup RID data */ data.dsize = strlen(name) + 1; data.dptr = name; /* setup the RID index key */ slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, user_rid); key.dptr = keystr; key.dsize = strlen (keystr) + 1; /* add the reference */ if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) { DEBUG(0, ("Unable to modify TDB passwd !")); DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb))); DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr)); ret = False; goto done; } done: /* cleanup */ tdb_close (pwd_tdb); SAFE_FREE(buf); return (ret); }
static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from) { const char * vstring = TDBSAM_VERSION_STRING; SAM_ACCOUNT *user = NULL; const char *prefix = USERPREFIX; TDB_DATA data, key, old_key; uint8 *buf = NULL; BOOL ret; if (pdb_tdb == NULL) { DEBUG(0,("tdbsam_convert: Bad TDB Context pointer.\n")); return False; } /* handle a Samba upgrade */ tdb_lock_bystring(pdb_tdb, vstring, 0); if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) { DEBUG(0,("tdbsam_convert: cannot initialized a SAM_ACCOUNT.\n")); return False; } /* Enumerate all records and convert them */ key = tdb_firstkey(pdb_tdb); while (key.dptr) { /* skip all non-USER entries (eg. RIDs) */ while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) { old_key = key; /* increment to next in line */ key = tdb_nextkey(pdb_tdb, key); SAFE_FREE(old_key.dptr); } if (key.dptr) { /* read from tdbsam */ data = tdb_fetch(pdb_tdb, key); if (!data.dptr) { DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr)); return False; } if (!NT_STATUS_IS_OK(pdb_reset_sam(user))) { DEBUG(0,("tdbsam_convert: cannot reset SAM_ACCOUNT.\n")); SAFE_FREE(data.dptr); return False; } /* unpack the buffer from the former format */ DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from)); switch (from) { case 0: ret = init_sam_from_buffer_v0(user, (uint8 *)data.dptr, data.dsize); break; case 1: ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize); break; default: /* unknown tdbsam version */ ret = False; } if (!ret) { DEBUG(0,("tdbsam_convert: Bad SAM_ACCOUNT entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from)); SAFE_FREE(data.dptr); return False; } /* pack from the buffer into the new format */ DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from)); if ((data.dsize=init_buffer_from_sam (&buf, user, False)) == -1) { DEBUG(0,("tdbsam_convert: cannot pack the SAM_ACCOUNT into the new format\n")); SAFE_FREE(data.dptr); return False; } data.dptr = (char *)buf; /* Store the buffer inside the TDBSAM */ if (tdb_store(pdb_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) { DEBUG(0,("tdbsam_convert: cannot store the SAM_ACCOUNT (key:%s) in new format\n",key.dptr)); SAFE_FREE(data.dptr); return False; } SAFE_FREE(data.dptr); /* increment to next in line */ old_key = key; key = tdb_nextkey(pdb_tdb, key); SAFE_FREE(old_key.dptr); } } pdb_free_sam(&user); /* upgrade finished */ tdb_store_int32(pdb_tdb, vstring, TDBSAM_VERSION); tdb_unlock_bystring(pdb_tdb, vstring); return(True); }