idmap_tdb.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 677 行 · 第 1/2 页

C
677
字号
		TDB_DATA sid_data;		TDB_DATA ugid_data;		fstring sid_string;				sid_to_string(sid_string, sid);				sid_data.dptr = sid_string;		sid_data.dsize = strlen(sid_string)+1;		/* Lock the record for this SID. */		if (tdb_chainlock(idmap_tdb, sid_data) != 0) {			DEBUG(10,("db_get_id_from_sid: failed to lock record %s. Error %s\n",					sid_string, tdb_errorstr(idmap_tdb) ));			return NT_STATUS_UNSUCCESSFUL;		}		do {			fstring ugid_str;			/* Allocate a new id for this sid */			ret = db_allocate_id(id, *id_type);			if (!NT_STATUS_IS_OK(ret))				break;						/* Store the UID side */			/* Store new id */			if (*id_type & ID_USERID) {				slprintf(ugid_str, sizeof(ugid_str), "UID %lu", 					 (unsigned long)((*id).uid));			} else {				slprintf(ugid_str, sizeof(ugid_str), "GID %lu", 					 (unsigned long)((*id).gid));			}						ugid_data.dptr = ugid_str;			ugid_data.dsize = strlen(ugid_str) + 1;			DEBUG(10,("db_get_id_from_sid: storing %s -> %s\n",					ugid_data.dptr, sid_data.dptr ));			if (tdb_store(idmap_tdb, ugid_data, sid_data, TDB_INSERT) != -1) {				ret = NT_STATUS_OK;				break;			}			if (tdb_error(idmap_tdb) != TDB_ERR_EXISTS)				DEBUG(10,("db_get_id_from_sid: error %s\n", tdb_errorstr(idmap_tdb) ));			ret = NT_STATUS_UNSUCCESSFUL;		} while (tdb_error(idmap_tdb) == TDB_ERR_EXISTS);		if (NT_STATUS_IS_OK(ret)) {			DEBUG(10,("db_get_id_from_sid: storing %s -> %s\n",				sid_data.dptr, ugid_data.dptr ));			if (tdb_store(idmap_tdb, sid_data, ugid_data, TDB_REPLACE) == -1) {				DEBUG(10,("db_get_id_from_sid: error %s\n", tdb_errorstr(idmap_tdb) ));				/* TODO: print tdb error !! */				tdb_chainunlock(idmap_tdb, sid_data);				return NT_STATUS_UNSUCCESSFUL;			}		}		tdb_chainunlock(idmap_tdb, sid_data);	}		return ret;}static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type){	TDB_DATA ksid, kid, data;	fstring ksidstr;	fstring kidstr;	DEBUG(10,("db_set_mapping: id_type = 0x%x\n", id_type));	if (!sid)		return NT_STATUS_INVALID_PARAMETER;	sid_to_string(ksidstr, sid);	ksid.dptr = ksidstr;	ksid.dsize = strlen(ksidstr) + 1;	if (id_type & ID_USERID) {		slprintf(kidstr, sizeof(kidstr), "UID %lu", (unsigned long)id.uid);	} else if (id_type & ID_GROUPID) {		slprintf(kidstr, sizeof(kidstr), "GID %lu", (unsigned long)id.gid);	} else {		return NT_STATUS_INVALID_PARAMETER;	}	kid.dptr = kidstr;	kid.dsize = strlen(kidstr) + 1;	/* *DELETE* prevoius mappings if any.	 * This is done both SID and [U|G]ID passed in */		/* Lock the record for this SID. */	if (tdb_chainlock(idmap_tdb, ksid) != 0) {		DEBUG(10,("db_set_mapping: failed to lock record %s. Error %s\n",				ksidstr, tdb_errorstr(idmap_tdb) ));		return NT_STATUS_UNSUCCESSFUL;	}	DEBUG(10,("db_set_mapping: fetching %s\n", ksid.dptr));	data = tdb_fetch(idmap_tdb, ksid);	if (data.dptr) {		DEBUG(10,("db_set_mapping: deleting %s and %s\n", data.dptr, ksid.dptr ));		tdb_delete(idmap_tdb, data);		tdb_delete(idmap_tdb, ksid);		SAFE_FREE(data.dptr);	}	data = tdb_fetch(idmap_tdb, kid);	if (data.dptr) {		DEBUG(10,("db_set_mapping: deleting %s and %s\n", data.dptr, kid.dptr ));		tdb_delete(idmap_tdb, data);		tdb_delete(idmap_tdb, kid);		SAFE_FREE(data.dptr);	}	if (tdb_store(idmap_tdb, ksid, kid, TDB_INSERT) == -1) {		DEBUG(0, ("idb_set_mapping: tdb_store 1 error: %s\n", tdb_errorstr(idmap_tdb)));		tdb_chainunlock(idmap_tdb, ksid);		return NT_STATUS_UNSUCCESSFUL;	}	if (tdb_store(idmap_tdb, kid, ksid, TDB_INSERT) == -1) {		DEBUG(0, ("idb_set_mapping: tdb_store 2 error: %s\n", tdb_errorstr(idmap_tdb)));		tdb_chainunlock(idmap_tdb, ksid);		return NT_STATUS_UNSUCCESSFUL;	}	tdb_chainunlock(idmap_tdb, ksid);	DEBUG(10,("db_set_mapping: stored %s -> %s and %s -> %s\n", ksid.dptr, kid.dptr, kid.dptr, ksid.dptr ));	return NT_STATUS_OK;}/***************************************************************************** Initialise idmap database. *****************************************************************************/static NTSTATUS db_idmap_init( char *params ){	SMB_STRUCT_STAT stbuf;	char *tdbfile = NULL;	int32 version;	BOOL tdb_is_new = False;	/* use the old database if present */	tdbfile = SMB_STRDUP(lock_path("winbindd_idmap.tdb"));	if (!tdbfile) {		DEBUG(0, ("idmap_init: out of memory!\n"));		return NT_STATUS_NO_MEMORY;	}	if (!file_exist(tdbfile, &stbuf)) {		tdb_is_new = True;	}	DEBUG(10,("db_idmap_init: Opening tdbfile %s\n", tdbfile ));	/* Open idmap repository */	if (!(idmap_tdb = tdb_open_log(tdbfile, 0,				       TDB_DEFAULT, O_RDWR | O_CREAT,				       0644))) {		DEBUG(0, ("idmap_init: Unable to open idmap database\n"));		SAFE_FREE(tdbfile);		return NT_STATUS_UNSUCCESSFUL;	}	SAFE_FREE(tdbfile);	if (tdb_is_new) {		/* the file didn't existed before opening it, let's		 * store idmap version as nobody else yet opened and		 * stored it. I do not like this method but didn't		 * found a way to understand if an opened tdb have		 * been just created or not --- SSS */		tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION);	}	/* check against earlier versions */	version = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");	if (version != IDMAP_VERSION) {		DEBUG(0, ("idmap_init: Unable to open idmap database, it's in an old format!\n"));		return NT_STATUS_INTERNAL_DB_ERROR;	}	/* Create high water marks for group and user id */	if (!lp_idmap_uid(&idmap_state.uid_low, &idmap_state.uid_high)) {		DEBUG(1, ("idmap uid range missing or invalid\n"));		DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));	} else {		if (tdb_fetch_int32(idmap_tdb, HWM_USER) == -1) {			if (tdb_store_int32(idmap_tdb, HWM_USER, idmap_state.uid_low) == -1) {				DEBUG(0, ("idmap_init: Unable to initialise user hwm in idmap database\n"));				return NT_STATUS_INTERNAL_DB_ERROR;			}		}	}	if (!lp_idmap_gid(&idmap_state.gid_low, &idmap_state.gid_high)) {		DEBUG(1, ("idmap gid range missing or invalid\n"));		DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));	} else {		if (tdb_fetch_int32(idmap_tdb, HWM_GROUP) == -1) {			if (tdb_store_int32(idmap_tdb, HWM_GROUP, idmap_state.gid_low) == -1) {				DEBUG(0, ("idmap_init: Unable to initialise group hwm in idmap database\n"));				return NT_STATUS_INTERNAL_DB_ERROR;			}		}	}	return NT_STATUS_OK;}/* Close the tdb */static NTSTATUS db_idmap_close(void){	if (idmap_tdb) {		if (tdb_close(idmap_tdb) == 0) {			return NT_STATUS_OK;		} else {			return NT_STATUS_UNSUCCESSFUL;		}	}	return NT_STATUS_OK;}/* Dump status information to log file.  Display different stuff based on   the debug level:   Debug Level        Information Displayed   =================================================================   0                  Percentage of [ug]id range allocated   0                  High water marks (next allocated ids)*/#define DUMP_INFO 0static void db_idmap_status(void){	int user_hwm, group_hwm;	DEBUG(0, ("winbindd idmap status:\n"));	/* Get current high water marks */	if ((user_hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) {		DEBUG(DUMP_INFO,		      ("\tCould not get userid high water mark!\n"));	}	if ((group_hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) {		DEBUG(DUMP_INFO,		      ("\tCould not get groupid high water mark!\n"));	}	/* Display next ids to allocate */	if (user_hwm != -1) {		DEBUG(DUMP_INFO,		      ("\tNext userid to allocate is %d\n", user_hwm));	}	if (group_hwm != -1) {		DEBUG(DUMP_INFO,		      ("\tNext groupid to allocate is %d\n", group_hwm));	}	/* Display percentage of id range already allocated. */	if (user_hwm != -1) {		int num_users = user_hwm - idmap_state.uid_low;		int total_users =		    idmap_state.uid_high - idmap_state.uid_low;		DEBUG(DUMP_INFO,		      ("\tUser id range is %d%% full (%d of %d)\n",		       num_users * 100 / total_users, num_users,		       total_users));	}	if (group_hwm != -1) {		int num_groups = group_hwm - idmap_state.gid_low;		int total_groups =		    idmap_state.gid_high - idmap_state.gid_low;		DEBUG(DUMP_INFO,		      ("\tGroup id range is %d%% full (%d of %d)\n",		       num_groups * 100 / total_groups, num_groups,		       total_groups));	}	/* Display complete mapping of users and groups to rids */}/********************************************************************** Return the TDB_CONTEXT* for winbindd_idmap.  I **really** feel dirty doing this, but not so dirty that I want to create another  tdb***********************************************************************/TDB_CONTEXT *idmap_tdb_handle( void ){	if ( idmap_tdb )		return idmap_tdb;			/* go ahead an open it;  db_idmap_init() doesn't use any params 	   right now */	   	db_idmap_init( NULL );	if ( idmap_tdb )		return idmap_tdb;			return NULL;}static struct idmap_methods db_methods = {	db_idmap_init,	db_allocate_rid,	db_allocate_id,	db_get_sid_from_id,	db_get_id_from_sid,	db_set_mapping,	db_idmap_close,	db_idmap_status};NTSTATUS idmap_tdb_init(void){	return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb", &db_methods);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?