summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/lookup_sid.c488
-rw-r--r--source3/passdb/passdb.c105
-rw-r--r--source3/passdb/pdb_interface.c4
-rw-r--r--source3/passdb/pdb_ldap.c21
-rw-r--r--source3/passdb/pdb_mysql.c4
-rw-r--r--source3/passdb/pdb_plugin.c8
-rw-r--r--source3/passdb/pdb_tdb.c6
-rw-r--r--source3/passdb/secrets.c61
8 files changed, 666 insertions, 31 deletions
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
new file mode 100644
index 0000000000..f84ff28db9
--- /dev/null
+++ b/source3/passdb/lookup_sid.c
@@ -0,0 +1,488 @@
+/*
+ Unix SMB/CIFS implementation.
+ uid/user handling
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Gerald (Jerry) Carter 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*****************************************************************
+ *THE CANONICAL* convert name to SID function.
+ Tries local lookup first - for local domains - then uses winbind.
+*****************************************************************/
+
+BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
+{
+ fstring sid;
+ BOOL local_lookup = False;
+
+ *name_type = SID_NAME_UNKNOWN;
+
+ /* If we are looking up a domain user, make sure it is
+ for the local machine only */
+
+ if (strequal(global_myname(), domain)) {
+ local_lookup = True;
+ } else if (lp_server_role() == ROLE_DOMAIN_PDC ||
+ lp_server_role() == ROLE_DOMAIN_BDC) {
+ if (strequal(domain, lp_workgroup())) {
+ local_lookup = True;
+ }
+ }
+
+ if (local_lookup) {
+ if (local_lookup_name(name, psid, name_type)) {
+ DEBUG(10,
+ ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n",
+ domain, name, sid_to_string(sid,psid),
+ sid_type_lookup(*name_type), (unsigned int)*name_type));
+ return True;
+ }
+ } else {
+ /* Remote */
+ if (winbind_lookup_name(domain, name, psid, name_type)) {
+
+ DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
+ domain, name, sid_to_string(sid, psid),
+ (unsigned int)*name_type));
+ return True;
+ }
+ }
+
+ DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n",
+ local_lookup ? "local" : "winbind", domain, name));
+
+ return False;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to name function.
+ Tries local lookup first - for local sids, then tries winbind.
+*****************************************************************/
+
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
+{
+ if (!name_type)
+ return False;
+
+ *name_type = SID_NAME_UNKNOWN;
+
+ /* Check if this is our own sid. This should perhaps be done by
+ winbind? For the moment handle it here. */
+
+ if (sid->num_auths == 5) {
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+
+ if (sid_equal(get_global_sam_sid(), &tmp_sid)) {
+
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ local_lookup_sid(sid, name, name_type);
+ }
+ }
+
+ if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
+ fstring sid_str;
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ lookup_known_rid(&tmp_sid, rid, name, name_type);
+ }
+ return True;
+}
+
+
+/*****************************************************************
+ Id mapping cache. This is to avoid Winbind mappings already
+ seen by smbd to be queried too frequently, keeping winbindd
+ busy, and blocking smbd while winbindd is busy with other
+ stuff. Written by Michael Steffens <michael.steffens@hp.com>,
+ modified to use linked lists by jra.
+*****************************************************************/
+
+#define MAX_UID_SID_CACHE_SIZE 100
+#define TURNOVER_UID_SID_CACHE_SIZE 10
+#define MAX_GID_SID_CACHE_SIZE 100
+#define TURNOVER_GID_SID_CACHE_SIZE 10
+
+static size_t n_uid_sid_cache = 0;
+static size_t n_gid_sid_cache = 0;
+
+static struct uid_sid_cache {
+ struct uid_sid_cache *next, *prev;
+ uid_t uid;
+ DOM_SID sid;
+ enum SID_NAME_USE sidtype;
+} *uid_sid_cache_head;
+
+static struct gid_sid_cache {
+ struct gid_sid_cache *next, *prev;
+ gid_t gid;
+ DOM_SID sid;
+ enum SID_NAME_USE sidtype;
+} *gid_sid_cache_head;
+
+/*****************************************************************
+ Find a SID given a uid.
+*****************************************************************/
+
+static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
+{
+ struct uid_sid_cache *pc;
+
+ for (pc = uid_sid_cache_head; pc; pc = pc->next) {
+ if (pc->uid == uid) {
+ fstring sid;
+ *psid = pc->sid;
+ DEBUG(3,("fetch sid from uid cache %u -> %s\n",
+ (unsigned int)uid, sid_to_string(sid, psid)));
+ DLIST_PROMOTE(uid_sid_cache_head, pc);
+ return True;
+ }
+ }
+ return False;
+}
+
+/*****************************************************************
+ Find a uid given a SID.
+*****************************************************************/
+
+static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
+{
+ struct uid_sid_cache *pc;
+
+ for (pc = uid_sid_cache_head; pc; pc = pc->next) {
+ if (sid_compare(&pc->sid, psid) == 0) {
+ fstring sid;
+ *puid = pc->uid;
+ DEBUG(3,("fetch uid from cache %u -> %s\n",
+ (unsigned int)*puid, sid_to_string(sid, psid)));
+ DLIST_PROMOTE(uid_sid_cache_head, pc);
+ return True;
+ }
+ }
+ return False;
+}
+
+/*****************************************************************
+ Store uid to SID mapping in cache.
+*****************************************************************/
+
+static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
+{
+ struct uid_sid_cache *pc;
+
+ if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) {
+ /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */
+ struct uid_sid_cache *pc_next;
+ size_t i;
+
+ for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next)
+ ;
+ for(; pc; pc = pc_next) {
+ pc_next = pc->next;
+ DLIST_REMOVE(uid_sid_cache_head,pc);
+ SAFE_FREE(pc);
+ n_uid_sid_cache--;
+ }
+ }
+
+ pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache));
+ if (!pc)
+ return;
+ pc->uid = uid;
+ sid_copy(&pc->sid, psid);
+ DLIST_ADD(uid_sid_cache_head, pc);
+ n_uid_sid_cache++;
+}
+
+/*****************************************************************
+ Find a SID given a gid.
+*****************************************************************/
+
+static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
+{
+ struct gid_sid_cache *pc;
+
+ for (pc = gid_sid_cache_head; pc; pc = pc->next) {
+ if (pc->gid == gid) {
+ fstring sid;
+ *psid = pc->sid;
+ DEBUG(3,("fetch sid from gid cache %u -> %s\n",
+ (unsigned int)gid, sid_to_string(sid, psid)));
+ DLIST_PROMOTE(gid_sid_cache_head, pc);
+ return True;
+ }
+ }
+ return False;
+}
+
+/*****************************************************************
+ Find a gid given a SID.
+*****************************************************************/
+
+static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
+{
+ struct gid_sid_cache *pc;
+
+ for (pc = gid_sid_cache_head; pc; pc = pc->next) {
+ if (sid_compare(&pc->sid, psid) == 0) {
+ fstring sid;
+ *pgid = pc->gid;
+ DEBUG(3,("fetch uid from cache %u -> %s\n",
+ (unsigned int)*pgid, sid_to_string(sid, psid)));
+ DLIST_PROMOTE(gid_sid_cache_head, pc);
+ return True;
+ }
+ }
+ return False;
+}
+
+/*****************************************************************
+ Store gid to SID mapping in cache.
+*****************************************************************/
+
+static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
+{
+ struct gid_sid_cache *pc;
+
+ if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) {
+ /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */
+ struct gid_sid_cache *pc_next;
+ size_t i;
+
+ for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next)
+ ;
+ for(; pc; pc = pc_next) {
+ pc_next = pc->next;
+ DLIST_REMOVE(gid_sid_cache_head,pc);
+ SAFE_FREE(pc);
+ n_gid_sid_cache--;
+ }
+ }
+
+ pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache));
+ if (!pc)
+ return;
+ pc->gid = gid;
+ sid_copy(&pc->sid, psid);
+ DLIST_ADD(gid_sid_cache_head, pc);
+ n_gid_sid_cache++;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert uid_t to SID function.
+*****************************************************************/
+
+NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
+{
+ uid_t low, high;
+ fstring sid;
+
+ ZERO_STRUCTP(psid);
+
+ if (fetch_sid_from_uid_cache(psid, uid))
+ return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
+
+ if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) {
+ if (winbind_uid_to_sid(psid, uid)) {
+
+ DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)uid, sid_to_string(sid, psid)));
+
+ if (psid)
+ store_uid_sid_cache(psid, uid);
+ return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
+ }
+ }
+
+ if (!local_uid_to_sid(psid, uid)) {
+ DEBUG(10,("uid_to_sid: local %u failed to map to sid\n", (unsigned int)uid ));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
+
+ store_uid_sid_cache(psid, uid);
+ return NT_STATUS_OK;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert gid_t to SID function.
+*****************************************************************/
+
+NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+ gid_t low, high;
+ fstring sid;
+
+ ZERO_STRUCTP(psid);
+
+ if (fetch_sid_from_gid_cache(psid, gid))
+ return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
+
+ if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) {
+ if (winbind_gid_to_sid(psid, gid)) {
+
+ DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)gid, sid_to_string(sid, psid)));
+
+ if (psid)
+ store_gid_sid_cache(psid, gid);
+ return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
+ }
+ }
+
+ if (!local_gid_to_sid(psid, gid)) {
+ DEBUG(10,("gid_to_sid: local %u failed to map to sid\n", (unsigned int)gid ));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
+
+ store_gid_sid_cache(psid, gid);
+ return NT_STATUS_OK;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to uid function.
+*****************************************************************/
+
+NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
+{
+ fstring dom_name, name, sid_str;
+ enum SID_NAME_USE name_type;
+
+ if (fetch_uid_from_cache(puid, psid))
+ return NT_STATUS_OK;
+
+ /* if this is our SID then go straight to a local lookup */
+
+ if ( sid_compare_domain(get_global_sam_sid(), psid) == 0 ) {
+ DEBUG(10,("sid_to_uid: my domain (%s) - trying local.\n",
+ sid_string_static(psid) ));
+
+ if ( local_sid_to_uid(puid, psid, &name_type) )
+ goto success;
+
+ DEBUG(10,("sid_to_uid: local lookup failed\n"));
+
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* If it is not our local domain, only hope is winbindd */
+
+ if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) {
+ DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n",
+ sid_string_static(psid) ));
+
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* If winbindd does know the SID, ensure this is a user */
+
+ if (name_type != SID_NAME_USER) {
+ DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a user (%u)\n",
+ (unsigned int)name_type ));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* get the uid. Has to work or else we are dead in the water */
+
+ if ( !winbind_sid_to_uid(puid, psid) ) {
+ DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n",
+ sid_to_string(sid_str, psid) ));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+success:
+ DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid),
+ (unsigned int)*puid ));
+
+ store_uid_sid_cache(psid, *puid);
+
+ return NT_STATUS_OK;
+}
+/*****************************************************************
+ *THE CANONICAL* convert SID to gid function.
+ Group mapping is used for gids that maps to Wellknown SIDs
+*****************************************************************/
+
+NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
+{
+ fstring dom_name, name, sid_str;
+ enum SID_NAME_USE name_type;
+
+ if (fetch_gid_from_cache(pgid, psid))
+ return NT_STATUS_OK;
+
+ /*
+ * First we must look up the name and decide if this is a group sid.
+ * Group mapping can deal with foreign SIDs
+ */
+
+ if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
+ DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
+ sid_to_string(sid_str, psid) ));
+
+ if ( local_sid_to_gid(pgid, psid, &name_type) )
+ goto success;
+
+ DEBUG(10,("sid_to_gid: no one knows this SID\n"));
+
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* winbindd knows it; Ensure this is a group sid */
+
+ if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) {
+ DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
+ (unsigned int)name_type ));
+
+ /* winbindd is running and knows about this SID. Just the wrong type.
+ Don't fallback to a local lookup here */
+
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* winbindd knows it and it is a type of group; sid_to_gid must succeed
+ or we are dead in the water */
+
+ if ( !winbind_sid_to_gid(pgid, psid) ) {
+ DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n",
+ sid_to_string(sid_str, psid) ));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+success:
+ DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid),
+ (unsigned int)*pgid ));
+
+ store_gid_sid_cache(psid, *pgid);
+
+ return NT_STATUS_OK;
+}
+
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index e440e064ef..76745be3f0 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -758,13 +758,27 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
if (fallback_pdb_rid_is_user(rid)) {
uid_t uid;
+ struct passwd *pw = NULL;
DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
uid = fallback_pdb_user_rid_to_uid(rid);
- slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
-
- return False; /* Indicates that this user was 'not mapped' */
+ pw = sys_getpwuid( uid );
+
+ DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
+ pw ? "succeeded" : "failed" ));
+
+ if ( !pw )
+ fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
+ else
+ fstrcpy( name, pw->pw_name );
+
+ DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
+ (unsigned int)rid ));
+
+ *psid_name_use = SID_NAME_USER;
+
+ return ( pw != NULL );
} else {
gid_t gid;
struct group *gr;
@@ -779,16 +793,19 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
gr ? "succeeded" : "failed" ));
- if(!gr) {
- slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
- return False; /* Indicates that this group was 'not mapped' */
- }
-
- fstrcpy( name, gr->gr_name);
+ if( !gr )
+ fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
+ else
+ fstrcpy( name, gr->gr_name);
DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
(unsigned int)rid ));
- return True;
+
+ /* assume fallback groups aer domain global groups */
+
+ *psid_name_use = SID_NAME_DOM_GRP;
+
+ return ( gr != NULL );
}
}
@@ -1156,11 +1173,18 @@ BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_
DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
{
GROUP_MAP group;
+ BOOL ret;
/* we don't need to disable winbindd since the gid is stored in
the GROUP_MAP object */
+
+ /* done as root since ldap backend requires root to open a connection */
- if ( !pdb_getgrgid( &group, gid ) ) {
+ become_root();
+ ret = pdb_getgrgid( &group, gid );
+ unbecome_root();
+
+ if ( !ret ) {
/* fallback to rid mapping if enabled */
@@ -1289,6 +1313,7 @@ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
BOOL ret = True;
uid_t uid = -1;
gid_t gid = -1;
+ struct passwd *pw = NULL;
if(sampass == NULL || buf == NULL) {
DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n"));
@@ -1296,7 +1321,7 @@ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
/* unpack the buffer into variables */
- len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING,
+ len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING,
&logon_time,
&logoff_time,
&kickoff_time,
@@ -1344,6 +1369,12 @@ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
pdb_set_nt_username(sampass, nt_username, PDB_SET);
pdb_set_fullname(sampass, fullname, PDB_SET);
+
+ if ( (pw=Get_Pwnam(username)) != NULL ) {
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ }
+
if (homedir) {
pdb_set_homedir(sampass, homedir, PDB_SET);
}
@@ -1633,7 +1664,7 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_
}
/* now for the real call to tdb_pack() */
- buflen = tdb_pack(*buf, len, TDB_FORMAT_STRING,
+ buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING,
logon_time,
logoff_time,
kickoff_time,
@@ -1676,3 +1707,51 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_
return (buflen);
}
+
+
+/**********************************************************************
+**********************************************************************/
+
+static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
+{
+ uid_t u_low, u_high;
+ gid_t g_low, g_high;
+
+ if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
+ return False;
+ }
+
+ *low = (u_low < g_low) ? u_low : g_low;
+ *high = (u_high < g_high) ? u_high : g_high;
+
+ return True;
+}
+
+/******************************************************************
+ Get the the non-algorithmic RID range if idmap range are defined
+******************************************************************/
+
+BOOL get_free_rid_range(uint32 *low, uint32 *high)
+{
+ uint32 id_low, id_high;
+
+ if (!lp_enable_rid_algorithm()) {
+ *low = BASE_RID;
+ *high = (uint32)-1;
+ }
+
+ if (!get_free_ugid_range(&id_low, &id_high)) {
+ return False;
+ }
+
+ *low = fallback_pdb_uid_to_user_rid(id_low);
+ if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) {
+ *high = (uint32)-1;
+ } else {
+ *high = fallback_pdb_uid_to_user_rid(id_high);
+ }
+
+ return True;
+}
+
+
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 5ebc14030f..d548081e78 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -422,10 +422,10 @@ static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_c
if (p) {
*p = 0;
module_location = p+1;
- trim_string(module_location, " ", " ");
+ trim_char(module_location, ' ', ' ');
}
- trim_string(module_name, " ", " ");
+ trim_char(module_name, ' ', ' ');
DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index aee6495759..009425c5f6 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -333,6 +333,8 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
/* New Interface is being implemented here */
+#if 0 /* JERRY - not uesed anymore */
+
/**********************************************************************
Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
*********************************************************************/
@@ -385,6 +387,7 @@ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
return True;
}
+#endif
/**********************************************************************
Initialize SAM_ACCOUNT from an LDAP query
@@ -419,8 +422,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
uint32 hours_len;
uint8 hours[MAX_HOURS_LEN];
pstring temp;
+ struct passwd *pw = NULL;
uid_t uid = -1;
- gid_t gid = getegid();
+ gid_t gid = -1;
/*
* do a little initialization
@@ -455,6 +459,14 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
DEBUG(2, ("Entry found for user: %s\n", username));
+ /* I'm not going to fail here, since there are checks
+ higher up the cal stack to do this --jerry */
+
+ if ( (pw=Get_Pwnam(username)) != NULL ) {
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ }
+
pstrcpy(nt_username, username);
pstrcpy(domain, ldap_state->domain_name);
@@ -523,6 +535,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
}
+#if 0 /* JERRY -- not used anymore */
/*
* If so configured, try and get the values from LDAP
*/
@@ -541,6 +554,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
}
}
}
+#endif
if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp))
@@ -1685,7 +1699,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
return False;
}
- map->sid_name_use = (uint32)atol(temp);
+ map->sid_name_use = (enum SID_NAME_USE)atol(temp);
if ((map->sid_name_use < SID_NAME_USER) ||
(map->sid_name_use > SID_NAME_UNKNOWN)) {
@@ -2128,7 +2142,6 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
GROUP_MAP map;
GROUP_MAP *mapt;
int entries = 0;
- NTSTATUS nt_status;
*num_entries = 0;
*rmap = NULL;
@@ -2138,7 +2151,7 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
return NT_STATUS_ACCESS_DENIED;
}
- while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
+ while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
if (sid_name_use != SID_NAME_UNKNOWN &&
sid_name_use != map.sid_name_use) {
DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
diff --git a/source3/passdb/pdb_mysql.c b/source3/passdb/pdb_mysql.c
index d3eb7cb975..6c200be504 100644
--- a/source3/passdb/pdb_mysql.c
+++ b/source3/passdb/pdb_mysql.c
@@ -240,9 +240,9 @@ static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u)
pdb_set_unknown_str(u, row[16], PDB_SET);
pdb_set_munged_dial(u, row[17], PDB_SET);
- string_to_sid(&sid, row[18]);
+ if(row[18])string_to_sid(&sid, row[18]);
pdb_set_user_sid(u, &sid, PDB_SET);
- string_to_sid(&sid, row[19]);
+ if(row[19])string_to_sid(&sid, row[19]);
pdb_set_group_sid(u, &sid, PDB_SET);
if (pdb_gethexpwd(row[20], temp), PDB_SET)
diff --git a/source3/passdb/pdb_plugin.c b/source3/passdb/pdb_plugin.c
index ea67da23a5..027cd0b5d3 100644
--- a/source3/passdb/pdb_plugin.c
+++ b/source3/passdb/pdb_plugin.c
@@ -41,9 +41,11 @@ NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con
if (p) {
*p = 0;
plugin_location = p+1;
- trim_string(plugin_location, " ", " ");
- } else plugin_location = NULL;
- trim_string(plugin_name, " ", " ");
+ trim_char(plugin_location, ' ', ' ');
+ } else {
+ plugin_location = NULL;
+ }
+ trim_char(plugin_name, ' ', ' ');
DEBUG(5, ("Trying to load sam plugin %s\n", plugin_name));
dl_handle = sys_dlopen(plugin_name, RTLD_NOW );
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index 7c2156455a..c9a84f3242 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -133,7 +133,7 @@ static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *
}
/* unpack the buffer */
- if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
return nt_status;
@@ -213,7 +213,7 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT
}
/* unpack the buffer */
- if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
tdb_close(pwd_tdb);
@@ -390,7 +390,7 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
ret = False;
goto done;
}
- data.dptr = buf;
+ data.dptr = (char *)buf;
fstrcpy(name, pdb_get_username(newpwd));
strlower_m(name);
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index 23413e4026..8a146f0d68 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -58,7 +58,7 @@ void *secrets_fetch(const char *key, size_t *size)
secrets_init();
if (!tdb)
return NULL;
- kbuf.dptr = key;
+ kbuf.dptr = (char *)key;
kbuf.dsize = strlen(key);
dbuf = tdb_fetch(tdb, kbuf);
if (size)
@@ -74,9 +74,9 @@ BOOL secrets_store(const char *key, const void *data, size_t size)
secrets_init();
if (!tdb)
return False;
- kbuf.dptr = key;
+ kbuf.dptr = (char *)key;
kbuf.dsize = strlen(key);
- dbuf.dptr = data;
+ dbuf.dptr = (char *)data;
dbuf.dsize = size;
return tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) == 0;
}
@@ -90,7 +90,7 @@ BOOL secrets_delete(const char *key)
secrets_init();
if (!tdb)
return False;
- kbuf.dptr = key;
+ kbuf.dptr = (char *)key;
kbuf.dsize = strlen(key);
return tdb_delete(tdb, kbuf) == 0;
}
@@ -738,3 +738,56 @@ BOOL must_use_pdc( const char *domain )
}
+/*******************************************************************************
+ Store a complete AFS keyfile into secrets.tdb.
+*******************************************************************************/
+
+BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
+{
+ fstring key;
+
+ if ((cell == NULL) || (keyfile == NULL))
+ return False;
+
+ if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
+ return False;
+
+ slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
+ return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
+}
+
+/*******************************************************************************
+ Fetch the current (highest) AFS key from secrets.tdb
+*******************************************************************************/
+BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result)
+{
+ fstring key;
+ struct afs_keyfile *keyfile;
+ size_t size;
+ uint32 i;
+
+ slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
+
+ keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
+
+ if (keyfile == NULL)
+ return False;
+
+ if (size != sizeof(struct afs_keyfile)) {
+ SAFE_FREE(keyfile);
+ return False;
+ }
+
+ i = ntohl(keyfile->nkeys);
+
+ if (i > SECRETS_AFS_MAXKEYS) {
+ SAFE_FREE(keyfile);
+ return False;
+ }
+
+ *result = keyfile->entry[i-1];
+
+ result->kvno = ntohl(result->kvno);
+
+ return True;
+}