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 + -
显示快捷键?