user.cpp
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:23k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
  2. // Copyright 1996 by Jarle Aase. All rights reserved.
  3. // See the "War Software Series Licende Agreement" for details concerning 
  4. // use and distribution.
  5. // ---
  6. // This source code, executables and programs containing source code or
  7. // binaries or proprietetary technology from the War Software Series are
  8. // NOT alloed used, viewed or tested by any governmental agencies in
  9. // any countries. This includes the government, departments, police, 
  10. // military etc.
  11. // ---
  12. // This file is intended for use with Tab space = 2
  13. // Created and maintained in MSVC Developer Studio
  14. // ---
  15. // NAME : user.cpp
  16. // PURPOSE : User management
  17. // PROGRAM : 
  18. // DATE : Sept. 28 1996
  19. // AUTHOR : Jarle Aase
  20. // ---
  21. // REVISION HISTORY
  22. // 
  23. #include "stdafx.h"
  24. #include "WarDaemon.h"
  25. #include "User.h"
  26. #ifdef _DEBUG
  27. #define new DEBUG_NEW
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. CUsr *CUsr::m_pUserMngr = NULL;
  32. LPCSTR CUsr::m_pIniFile = ".\User.ini";
  33. CLog *CUsr::m_Log = NULL;
  34. int CUsr::m_NextUserNum;
  35. CUsr::CUsr()
  36. {
  37. m_pUserMngr = this;
  38. }
  39. CUsr::~CUsr()
  40. {
  41. m_pUserMngr = NULL;
  42. m_Log = NULL;
  43. }
  44. BOOL CUsr::Create(CLog *Log)
  45. {
  46. m_Log = Log;
  47. ::GetIniItem(NULL, m_pIniFile, "@hdr@", "Next", m_NextUserNum, 0);
  48. if (!m_NextUserNum)
  49. {
  50. int sSystem, cSysAdmin, cUser, cVisitor;
  51. m_NextUserNum++;
  52. LogMsg(LOGF_SYSTEM,"Creating new user database.");
  53. // Create user database
  54. int User;
  55. sSystem = User = AddUser(UT_SYSTEM, "System", 2, USERPRI_ANON);
  56. if (!User)
  57. {
  58. LogMsg(LOGF_ERROR,"Failed to create System.");
  59. return FALSE;
  60. }
  61. SetParam(User,"Home","/");
  62. SetParam(User,"Root","/");
  63. SetParam(User,"RemoteAdmin Access", TRUE);
  64. SetParam(User,"FTP Access", TRUE);
  65. SetParam(User,"IP Shitlist", "*.gov;*.mil;*.gov.*;*.mil.*");
  66. SetParam(User,"Enable IP Shitlist", TRUE);
  67. SetParam(User,"Umask", 22);
  68. User = cVisitor = AddUser(UT_CLASS, "Visitor", TRUE, USERPRI_ANON);
  69. SetParam(User,"FTP Access", TRUE);
  70. SetParam(User,"AssignFilesTo", "LocalAdmin");
  71. User = cUser = AddUser(UT_CLASS, "User", FALSE, USERPRI_ANON);
  72. SetParam(User,"FTP Access", TRUE);
  73. User = cSysAdmin = AddUser(UT_CLASS, "Sysadmin", 2, USERPRI_ANON);
  74. SetParam(User,"FTP Access", TRUE);
  75. SetParam(User,"RemoteAdmin Access", TRUE);
  76. User = AddUser(UT_USER,"Anonymous", TRUE, USERPRI_ANON);
  77. SetParam(User,"Class", cVisitor);
  78. SetParam(User,"PWmode", PW_EMAIL);
  79. CreateAlias("Anonymous", "ftp");
  80. CreateAlias("Anonymous", "guest");
  81. User = AddUser(UT_GROUP,"Ftp", FALSE, USERPRI_ANON);
  82. SetParam(User,"Class", cUser);
  83. SetParam(User,"FTP Access", TRUE);
  84. // Create system user for maintainance
  85. User = AddUser(UT_USER, "LocalAdmin", 2, USERPRI_ADMIN);
  86. if (!User)
  87. {
  88. LogMsg(LOGF_ERROR,"Failed to create Local Admin user.");
  89. return FALSE;
  90. }
  91. SetParam(User,"Class", cSysAdmin);
  92. SetParam(User,"PWmode", PW_NORMAL);
  93. SetParam(User,"Home","/");
  94. SetParam(User,"Root","/");
  95. SetParam(User,"Administrator",TRUE);
  96. SetParam(User,"Local Only",TRUE);
  97. SetParam(User,"Password","sd&jkfhw387r");
  98. SetParam(User,"RemoteAdmin Access",TRUE);
  99. SetParam(User,"FTP Access",TRUE);
  100. // Create support user for maintainance
  101. User = AddUser(UT_USER, "SupportAdmin", TRUE, USERPRI_ADMIN);
  102. if (!User)
  103. {
  104. LogMsg(LOGF_ERROR,"Failed to create Support Admin user.");
  105. return FALSE;
  106. }
  107. SetParam(User,"Class", cSysAdmin);
  108. SetParam(User,"PWmode", PW_NORMAL);
  109. SetParam(User,"Home","/");
  110. SetParam(User,"Root","/");
  111. SetParam(User,"Administrator",TRUE);
  112. SetParam(User,"Password","sd&jkfhw387r");
  113. SetParam(User,"RemoteAdmin Access",FALSE);
  114. SetParam(User,"FTP Access",FALSE);
  115. }
  116. return TRUE;
  117. }
  118. BOOL CUsr::CreateAlias(LPCSTR Name, LPCSTR Alias)
  119. {
  120. int OrgUser = FindUser(UT_USER, Name), User;
  121. if (FindUser(UT_USER, Alias))
  122. {
  123. LogMsg(LOGF_WARNINGS,"Failed to create alias '%s' for user '%s'. Alias name exist.",
  124. Alias, Name);
  125. return FALSE;
  126. }
  127. if (!OrgUser)
  128. {
  129. LogMsg(LOGF_WARNINGS,"Failed to create alias '%s' for user '%s'. User not found.",
  130. Alias, Name);
  131. return FALSE;
  132. }
  133. CString cBuf;
  134. if ((User = AddUser(UT_USER, Alias)) == INVALID_USER_VALUE)
  135. return FALSE;
  136. SetParam(User, "Alias to", OrgUser);
  137. LogMsg(LOGF_SYSTEM,"Created alias name '%s' for user '%s'", Alias, Name);
  138. return TRUE;
  139. }
  140. void CUsr::SetParam(int UserNum, LPCSTR Key, LPCSTR Value)
  141. {
  142. CString cSection;
  143. char buf[128];
  144. // Special cases
  145. if (Value && *Value && !stricmp(Key, "password"))
  146. {
  147. Value = crypt(Value, "", buf);
  148. }
  149. cSection.Format("U %d", UserNum);
  150. ::PutIniItem(NULL, m_pIniFile, cSection, Key, Value);
  151. }
  152. void CUsr::SetParam(int UserNum, LPCSTR Key, int Value)
  153. {
  154. CString cSection;
  155. cSection.Format("U %d", UserNum);
  156. ::PutIniItem(NULL, m_pIniFile, cSection, Key, Value);
  157. }
  158. int CUsr::GetParam(int UserNum, LPCSTR Key, int DefValue)
  159. {
  160. CString cSection;
  161. int Value;
  162. cSection.Format("U %d", UserNum);
  163. ::GetIniItem(NULL, m_pIniFile, cSection, Key, Value, DefValue);
  164. return Value;
  165. }
  166. LPCSTR CUsr::GetParam(int UserNum, LPCSTR Key, LPCSTR DefValue, CString& cBuf)
  167. {
  168. CString cSection;
  169. cSection.Format("U %d", UserNum);
  170. ::GetIniItem(NULL, m_pIniFile, cSection, Key, cBuf, DefValue);
  171. return cBuf.IsEmpty() ? NULL : (LPCSTR)cBuf;
  172. }
  173. int CUsr::AddUser(int UserType, LPCSTR UserID, BOOL Protect, int PrivLevel)
  174. {
  175. ASSERT(AfxIsValidString(UserID));
  176. ASSERT(UserType >= UT_USER);
  177. ASSERT(UserType < UT_INVALID);
  178. ASSERT(PrivLevel >= USERPRI_ANON);
  179. ASSERT(PrivLevel < USERPRI_INVALID);
  180. ASSERT((Protect == TRUE) || (Protect == FALSE) || (Protect == 2));
  181. CString cUserID, cBuf;
  182. if (FindUser(UserType, UserID))
  183. {
  184. LogMsg(LOGF_DEBUG,"AddUser() User '%s' exist. Cannot add user.", UserID);
  185. return 0;
  186. }
  187. // Refresh just in case...
  188. ::GetIniItem(NULL, m_pIniFile, "@hdr@", "Next", m_NextUserNum, 0);
  189. if (m_NextUserNum == 0)
  190. m_NextUserNum = 1;
  191. if (FindUser(m_NextUserNum, cBuf))
  192. {
  193. LogMsg(LOGF_ERROR,"AddUser() User number %d exist. Cannot add user.", m_NextUserNum);
  194. return 0;
  195. }
  196. // Update next user counter
  197. ::PutIniItem(NULL, m_pIniFile, "@hdr@", "Next", ++m_NextUserNum);
  198. // Update the name to number reference
  199. cUserID.Format("N %d %s", UserType, UserID);
  200. ::PutIniItem(NULL, m_pIniFile, cUserID, "UserNum", m_NextUserNum - 1);
  201. // Update the data record (section is number)
  202. cUserID.Format("U %d", m_NextUserNum - 1);
  203. ::PutIniItem(NULL, m_pIniFile, cUserID,  "UserID", UserID);
  204. ::PutIniItem(NULL, m_pIniFile, cUserID,  "Protect", Protect);
  205. ::PutIniItem(NULL, m_pIniFile, cUserID,  "PrivLevel", PrivLevel);
  206. ::PutIniItem(NULL, m_pIniFile, cUserID,  "Type", UserType);
  207. LogMsg(LOGF_SYSTEM,"AddUsr(): Added user #%d '%s'.", m_NextUserNum - 1, UserID);
  208. return m_NextUserNum -1;
  209. }
  210. // Find a user from user number
  211. // Return ID
  212. LPCSTR CUsr::FindUser(int UserNo, CString& cBuf)
  213. {
  214. CString cSection;
  215. cSection.Format("U %d", UserNo);
  216. ::GetIniItem(NULL, m_pIniFile, cSection, "UserID", cBuf, "");
  217. if (cBuf.IsEmpty())
  218. return NULL;
  219. return (LPCSTR)cBuf;
  220. }
  221. // Find a user from type and name
  222. // Return number
  223. int CUsr::FindUser(int UserType, LPCSTR UserID)
  224. {
  225. ASSERT(AfxIsValidString(UserID));
  226. ASSERT(UserType >= UT_USER);
  227. ASSERT(UserType < UT_INVALID);
  228. int UserNum = 0;
  229. CString cSection;
  230. cSection.Format("N %d %s", UserType, UserID);
  231. ::GetIniItem(NULL, m_pIniFile, cSection,  "UserNum", UserNum, 0);
  232. return UserNum;
  233. }
  234. void CUsr::LogMsg(int flag, LPCSTR Format, ...)
  235. {
  236. CString cBuf;
  237. if (!ShouldLog(m_Log, flag))
  238. return;
  239. ASSERT(AfxIsValidString(Format, FALSE));
  240. cBuf.Format("CUsr: %s", Format);
  241. va_list argList;
  242. va_start(argList, Format);
  243. m_Log->LogMsgV(flag, cBuf, argList);
  244. va_end(argList);
  245. }
  246. ///////////////////////////////////////////////////////////////////////////////////
  247. // Higher level 
  248. // General login function
  249. // Rerturns user number or 0 on failure.
  250. // Sends message back to the user
  251. int CUsr::Login(int LoginMode, LPCSTR UserID, LPCSTR Password, CTextSock *Sock)
  252. {
  253. int User;
  254. int PWmode = PW_NORMAL;
  255. CString cBuf, cKey;
  256. int err;
  257. LOGINPRMS lp;
  258. lp.LoginMode = LoginMode;
  259. lp.UserID = UserID;
  260. lp.Password = Password;
  261. lp.Sock = Sock;
  262. // First - let's check global options :-)
  263. switch(LoginMode)
  264. {
  265. case LT_REMOTE:
  266. if ((COptions::GetOption(COPTION_RA_DAEMON,RA_OPTIONS__ALLOWNETWORK) != "TRUE")
  267. && (Sock->m_PeerName != "127.0.0.1"))
  268. {
  269. Sock->LogMsg(LOGF_SECURITY,"Login rejected. Remote admin is not allowed over the network.");
  270. Sock->SendMsg(530, "Login rejected. Remote admin is not allowed over the network.");
  271. return 0;
  272. }
  273. break;
  274. }
  275. // EXT module
  276. if (err = PrcExt(CAPIHandler::OnLogin,0,(WPARAM)&User,(LPARAM)&lp))
  277. {
  278. if (err == CFuncList::AbortError)
  279. goto fool_me;
  280. if (err == CFuncList::OkAllDone)
  281. return User;
  282. }
  283. User = m_pUserMngr->FindUser(UT_USER, UserID);
  284. User = MapUser(User);
  285. if (User != INVALID_USER_VALUE)
  286. PWmode = m_pUserMngr->GetParam(User,"PWmode", PW_NORMAL);
  287. cKey.Format("%s Access", SafeStringIndex(CSock::DaemonTypes,LoginMode,LT_INVALID));
  288. Sock->m_IsLoggedInAnonymously = TRUE;
  289. if (!User || !m_pUserMngr->HasPermission(User, cKey))
  290. {
  291. // Update log
  292. if (User)
  293. Sock->LogMsg(LOGF_SECURITY,"Login rejected. User account '%s' is not authorized for %s.", 
  294. UserID, SafeStringIndex(CSock::DaemonTypes, Sock->m_Type, LT_INVALID));
  295. else
  296. Sock->LogMsg(LOGF_SECURITY,"Login attepmted to unknown user '%s'", UserID);
  297. fool_me:
  298. if (Password)
  299. goto deny_me;
  300. // Send message to user
  301. if (Sock)
  302. {
  303. Sock->SendMsg(331, "User name okay. Need password.");
  304. }
  305. return 0;
  306. }
  307. if (m_pUserMngr->GetParam(User, "Local Only", FALSE))
  308. {
  309. // User can only log on from local machine
  310. if (Sock->m_PeerName != Sock->m_HostName)
  311. {
  312. LogMsg(LOGF_SECURITY,
  313. "Login rejected. User account '%s' is only authorized for local access.", 
  314. UserID);
  315. goto fool_me;
  316. }
  317. }
  318. if (Password && *Password)
  319. {
  320. // EXT module
  321. if (err = PrcExt(CAPIHandler::OnPassword,0,(WPARAM)&User,(LPARAM)&lp))
  322. {
  323. if (err == CFuncList::AbortError)
  324. goto deny_me;
  325. if (err == CFuncList::OkAllDone)
  326. goto allow_me;
  327. }
  328. if (PWmode == PW_EMAIL)
  329. {
  330. CString cBuf("");
  331. LPCSTR p = Password;
  332. while(*p && (*p != '@'))
  333. cBuf += *(p++);
  334. if (!p || (*p != '@'))
  335. {
  336. // EXT module
  337. if (err = Sock->PrcSockExt(CSock::iOnBadPassword,0,0,(LPARAM)Password))
  338. {
  339. return 0;
  340. }
  341. Sock->LogMsg(LOGF_SECURITY,"Login rejected for user '%s'. Bad email address!", UserID);
  342. Sock->SendMsg(530, "Please use your full email address as password!");
  343. return 0;
  344. }
  345. Sock->m_LoginName.Format("%s@%s", cBuf, p[1] ? p : Sock->m_DNSName);
  346. Sock->SetName(Sock->m_LoginName);
  347. if (err = Sock->PrcSockExt(CSock::iOnVerifyLogin,1,(WPARAM)&User,(LPARAM)&lp))
  348. {
  349. if (err == CFuncList::AbortError)
  350. goto fool_me;
  351. if (err == CFuncList::OkAllDone)
  352. return User;
  353. }
  354. Sock->m_IsLoggedIn = TRUE;
  355. Sock->LogMsg(LOGF_INOUT,"%s Logged on anonymously with email '%s' as password", UserID, Password);
  356. }
  357. else if (PWmode == PW_NORMAL)
  358. {
  359. // Normal password
  360. m_pUserMngr->GetParam(User, "Password", "", cBuf);
  361. if (cBuf.IsEmpty())
  362. {
  363. Sock->LogMsg(LOGF_SECURITY,"Login rejected for user '%s'. Missing password!", UserID);
  364. goto deny_me;
  365. }
  366. if (!IsDES13validPwd(Password,m_pUserMngr->GetParam(User, "Password", "", cBuf)))
  367. {
  368. // Not accepted!
  369. Sock->LogMsg(LOGF_SECURITY,"Login rejected for user '%s'. Bad password!", UserID);
  370. deny_me:
  371. // EXT module
  372. if (err = Sock->PrcSockExt(CSock::iOnBadPassword,0,0,(LPARAM)Password))
  373. {
  374. return 0;
  375. }
  376. Sock->SendMsg(530, "User %s access denied....", UserID);
  377. return 0;
  378. }
  379. else
  380. {
  381. allow_me:
  382. Sock->m_IsLoggedInAnonymously = FALSE;
  383. Sock->m_LoginName = UserID;
  384. Sock->SetName(Sock->m_LoginName);
  385. if (err = Sock->PrcSockExt(CSock::iOnVerifyLogin,0,(WPARAM)&User,(LPARAM)&lp))
  386. {
  387. if (err == CFuncList::AbortError)
  388. goto fool_me;
  389. if (err == CFuncList::OkAllDone)
  390. return User;
  391. }
  392. Sock->m_IsLoggedIn = TRUE;
  393. Sock->LogMsg(LOGF_INOUT,"Logged on with normal password");
  394. }
  395. }
  396. else // No password
  397. goto skip_pwd;
  398. }
  399. else 
  400. {
  401. if (PWmode == PW_NORMAL)
  402. {
  403. Sock->SendMsg(331, "User name okay. Need password.");
  404. return 0;
  405. }
  406. else if (PWmode == PW_EMAIL)
  407. {
  408. Sock->SendMsg(331, "User name okay. Give your full email address as password.");
  409. return 0;
  410. }
  411. else
  412. {
  413. skip_pwd:
  414. Sock->m_LoginName = UserID;
  415. Sock->SetName(Sock->m_LoginName);
  416. if (err = Sock->PrcSockExt(CSock::iOnVerifyLogin,1,(WPARAM)&User,(LPARAM)&lp))
  417. {
  418. if (err == CFuncList::AbortError)
  419. goto fool_me;
  420. if (err == CFuncList::OkAllDone)
  421. return User;
  422. }
  423. Sock->m_IsLoggedIn = TRUE;
  424. Sock->LogMsg(LOGF_INOUT,"Logged on anonymously with no password");
  425. }
  426. }
  427. Sock->PrcSockExt(CSock::iOnHasLoggedOn,User,(WPARAM)UserID,(LPARAM)Password);
  428. return User;
  429. }
  430. // Is system administrator?
  431. BOOL CUsr::IsAdmin(int User)
  432. {
  433. return m_pUserMngr->GetParam(User, "Administrator", FALSE);
  434. }
  435. USER CUsr::GetUserClass(USER OrgUser)
  436. {
  437. int User = MapUser(OrgUser);
  438. return m_pUserMngr->GetParam(User, "Class", INVALID_USER_VALUE);
  439. }
  440. USER CUsr::GetUserGroup(USER OrgUser)
  441. {
  442. int User = MapUser(OrgUser);
  443. return m_pUserMngr->GetParam(User, "Group", INVALID_USER_VALUE);
  444. }
  445. USER CUsr::GetUserSystem(USER OrgUser)
  446. {
  447. int User = MapUser(OrgUser);
  448. USER System = m_pUserMngr->GetParam(User, "System", INVALID_USER_VALUE);
  449. if (System == INVALID_USER_VALUE)
  450. System =  m_pUserMngr->FindUser(UT_SYSTEM,"System");
  451. if (System == INVALID_USER_VALUE)
  452. LogMsg(LOGF_ERROR,"*** No system user in the user database!");
  453. return System;
  454. }
  455. int CUsr::GetType(USER OrgUser)
  456. {
  457. int User = MapUser(OrgUser);
  458. return m_pUserMngr->GetParam(User, "Type", 0);
  459. }
  460. USER CUsr::MapUser(USER User)
  461. {
  462. return GetParam(User,"Alias to", User);
  463. }
  464. BOOL CUsr::ListUsers(int Type, LPCSTR Pattern, CString& cBuf, BOOL IsInteractive)
  465. {
  466. cBuf.Empty();
  467. CString cNames, cTmp, cPwd;
  468. CString MyPattern;
  469. LPSTR p;
  470. int User;
  471. CString cAliasFor;
  472. int System = -2, Class = -2, Group = -2;
  473. int uSystem, uClass, uGroup;
  474. int Count = 0;
  475. int numidx = 5, nameidx = 24;
  476. int PWmode, Protected, nAliasFor;
  477. // Check to see if pattern is a specifier for System,Class,Group
  478. // Pattern can be either a tag[*] or System,Class,Group
  479. if (Pattern && strchr(Pattern,','))
  480. {
  481. if (sscanf(Pattern, "%d,%d,%d", &System, &Class, &Group) == 3)
  482. {
  483. // Move the pattern pointer beoind the stuff we just parsed...
  484. while(*Pattern)
  485. {
  486. if (isdigit(*Pattern) || (*Pattern == ',') || (*Pattern == '-') || isspace(*Pattern))
  487. ++Pattern;
  488. else
  489. break;
  490. }
  491. }
  492. else
  493. System = Class = Group = 0;
  494. }
  495. MyPattern.Format("N %d %s", Type, (Pattern && *Pattern) ? Pattern : "*");
  496. if (!::GetIniItemSectionNames(NULL, m_pIniFile, MyPattern, cNames))
  497. return FALSE;
  498. if (IsInteractive)
  499. cBuf.Format("%-24s %5s T %5s %5s %5s %5s %srn", 
  500. "Name", "Num", "Flags", "Syst", "Class", "Group", "Alias for");
  501. else
  502. {
  503. numidx = nameidx = 0;
  504. cBuf.Empty();
  505. }
  506. for(p = strtok(cNames.GetBuffer(1)," "); p; p = strtok(NULL," "))
  507. {
  508. if ((p = strtok(NULL," ")) == NULL)
  509. break;
  510. if ((p = strtok(NULL,"rn")) == NULL)
  511. break;
  512. if ((User = FindUser(Type, p)) == 0)
  513. continue;
  514. if ((nAliasFor = GetParam(User, "Alias to", INVALID_USER_VALUE)) != INVALID_USER_VALUE)
  515. {
  516. if (!FindUser(nAliasFor,cAliasFor))
  517. continue;
  518. }
  519. else
  520. cAliasFor.Empty();
  521. uSystem = GetUserSystem(User);
  522. uClass = GetUserClass(User);
  523. uGroup = GetUserGroup(User);
  524. // Check System, Class & Group limitations
  525. //if ((Class != INVALID_USER_VALUE) && /*(uClass != INVALID_USER_VALUE) &&*/ (Class != uClass))
  526. // continue;
  527. //
  528. //if ((System != INVALID_USER_VALUE) && (System != uSystem))
  529. // continue;
  530. //
  531. //if ((Group != INVALID_USER_VALUE) && /*(uGroup != INVALID_USER_VALUE) &&*/ (Group != uGroup))
  532. // continue;
  533. if ((Class != -2) && /*(uClass != INVALID_USER_VALUE) &&*/ (Class != uClass))
  534. continue;
  535. if ((System != -2) && (System != uSystem))
  536. continue;
  537. if ((Group != -2) && /*(uGroup != INVALID_USER_VALUE) &&*/ (Group != uGroup))
  538. continue;
  539. ++Count;
  540. PWmode = GetParam(User,"PWmode", PW_NORMAL);
  541. Protected = GetParam(User,"Protect", FALSE);
  542. cTmp.Format("%-*s %*d %d %c%c%c%c%c %*d %*d %*d %d %srn", 
  543. nameidx, p, 
  544. numidx, User, 
  545. GetType(User), 
  546. IsAdmin(User) ? 'A' : '-',
  547. GetParam(User,"FTP Access", FALSE) ? 'F' : '-',
  548. GetParam(User,"RemoteAdmin Access", FALSE) ? 'R' : '-',
  549. (PWmode == PW_NONE) ? 'n' : (PWmode == PW_EMAIL) ? 'e' : 'p',
  550. Protected == 1 ? 's' : Protected == 2 ? 'S' : '-',
  551. numidx, uSystem, 
  552. numidx, uClass, 
  553. numidx, uGroup,
  554. nAliasFor == INVALID_USER_VALUE ? 0 : nAliasFor,
  555. cAliasFor);
  556. cBuf += cTmp;
  557. }
  558. return Count > 0;
  559. }
  560. BOOL CUsr::ListUserParams(int Type, LPCSTR Name, CString& cBuf)
  561. {
  562. CString cKey;
  563. int User;
  564. if ((User = atoi(Name)) == 0) // Ignore type when using the number
  565. if ((User = FindUser(Type,Name)) == 0)
  566. return FALSE;
  567. cKey.Format("U %d", User);
  568. if (!::GetIniItemSection(NULL, m_pIniFile, cKey, NULL, cBuf))
  569. return FALSE;
  570. return TRUE;
  571. }
  572. BOOL CUsr::SetUserOption(int Type, LPCSTR Option)
  573. {
  574. LPSTR buf = strdup(Option), p;
  575. CString cKey;
  576. int User;
  577. int Rval = FALSE;
  578. if ((p = strtok(buf,"/")) == NULL)
  579. goto done;
  580. if ((User = atoi(p)) != 0) // Ignore type when using the number
  581. {
  582. if (!FindUser(User,cKey))
  583. goto done;
  584. }
  585. else if ((User = FindUser(Type,p)) == 0)
  586. goto done;
  587. if ((p = strtok(NULL,"=")) == NULL)
  588. goto done;
  589. cKey = p;
  590. p = strtok(NULL,"");
  591. SetParam(User, cKey, p ? p : "");
  592. Rval = TRUE;
  593. done:
  594. free(buf);
  595. return Rval;
  596. }
  597. BOOL CUsr::GetUserOption(int Type, LPCSTR Option, CString& cReturnValue)
  598. {
  599. LPSTR buf = strdup(Option), p;
  600. CString cKey;
  601. int User;
  602. int Rval = FALSE;
  603. if ((p = strtok(buf,"/")) == NULL)
  604. goto done;
  605. if ((User = atoi(p)) != 0) // Ignore type when using the number
  606. {
  607. if (!FindUser(User,cKey))
  608. goto done;
  609. }
  610. else if ((User = FindUser(Type,p)) == 0)
  611. goto done;
  612. if ((p = strtok(NULL,"=")) == NULL)
  613. goto done;
  614. cKey = p;
  615. p = strtok(NULL,"");
  616. if (!GetParam(User, cKey, p ? p : "", cReturnValue))
  617. goto done;
  618. Rval = TRUE;
  619. done:
  620. free(buf);
  621. return Rval;
  622. }
  623. // Recursive permission.
  624. // Only true if the whole path (from system to user) has the
  625. // permission.
  626. BOOL CUsr::HasPermission(USER User, LPCSTR Option)
  627. {
  628. int Parent;
  629. if (!GetParam(User, Option, FALSE))
  630. return FALSE;
  631. if ((Parent = GetUserGroup(User)) != INVALID_USER_VALUE)
  632. {
  633. if (!GetParam(Parent, Option, FALSE))
  634. return FALSE;
  635. }
  636. if ((Parent = GetUserClass(User)) != INVALID_USER_VALUE)
  637. {
  638. if (!GetParam(Parent, Option, FALSE))
  639. return FALSE;
  640. }
  641. if ((Parent = GetUserSystem(User)) != INVALID_USER_VALUE)
  642. {
  643. if (!GetParam(Parent, Option, FALSE))
  644. return FALSE;
  645. }
  646. return TRUE;
  647. }
  648. // Recursive permission.
  649. // Only true if the whole path (from system to user) has the
  650. // permission.
  651. LPCSTR CUsr::GetRecursiveParam(USER UserNum, LPCSTR Key, LPCSTR DefValue, CString& cBuf)
  652. {
  653. USER Parent;
  654. GetParam(UserNum, Key, "", cBuf);
  655. if (cBuf != "")
  656. return cBuf;
  657. if ((Parent = GetUserGroup(UserNum)) != INVALID_USER_VALUE)
  658. {
  659. GetParam(Parent, Key, "", cBuf);
  660. if (cBuf != "")
  661. return cBuf;
  662. }
  663. if ((Parent = GetUserClass(UserNum)) != INVALID_USER_VALUE)
  664. {
  665. GetParam(Parent, Key, "", cBuf);
  666. if (cBuf != "")
  667. return cBuf;
  668. }
  669. if ((Parent = GetUserSystem(UserNum)) != INVALID_USER_VALUE)
  670. {
  671. GetParam(Parent, Key, "", cBuf);
  672. if (cBuf != "")
  673. return cBuf;
  674. }
  675. cBuf = DefValue;
  676. return cBuf;
  677. }
  678. int CUsr::GetRecursiveParam(USER UserNum, LPCSTR Key, int DefValue)
  679. {
  680. CString cBuf, cValue;
  681. cBuf.Format("%d", DefValue);
  682. GetRecursiveParam(UserNum, Key, cBuf, cValue);
  683. return atoi(cValue);
  684. }
  685. // Delete user
  686. BOOL CUsr::DeleteUser(LPCSTR UserName)
  687. {
  688. USER User;
  689. CString cUserID, cBuf;
  690. int UserType;
  691. CString UserID;
  692. if ((User = atoi(UserName)) == 0)
  693. User = FindUser(UT_USER, UserName);
  694. if (!User || (User == INVALID_USER_VALUE) || !FindUser(User, cUserID))
  695. {
  696. LogMsg(LOGF_WARNINGS,"DeleteUser(%s) - Can't find the user.", UserName);
  697. return FALSE;
  698. }
  699. UserType = GetType(User);
  700. if (GetParam(User,"Protect",0))
  701. {
  702. LogMsg(LOGF_WARNINGS,"DeleteUser(%s) - User is protected.", UserName);
  703. return FALSE;
  704. }
  705. if (!atoi(UserName) && (cUserID != UserName))
  706. return DeleteAlias(UserName);
  707. cBuf.Format("N %d %s", UserType, cUserID);
  708. ::ResetSection(NULL, m_pIniFile, cBuf);
  709. cBuf.Format("U %d", User);
  710. ::ResetSection(NULL, m_pIniFile, cBuf);
  711. LogMsg(LOGF_SYSTEM,"User %s (%d) is deleted.", cUserID, User);
  712. return TRUE;
  713. }
  714. BOOL CUsr::DeleteAlias(LPCSTR AliasName)
  715. {
  716. CString cBuf;
  717. cBuf.Format("N 1 %s", AliasName);
  718. ::ResetSection(NULL, m_pIniFile, cBuf);
  719. return TRUE;
  720. }
  721. BOOL CUsr::RenameUser(LPCSTR UserName, LPCSTR NewName)
  722. {
  723. USER User;
  724. CString cUserID, cBuf;
  725. int UserType;
  726. CString UserID;
  727. if ((User = atoi(UserName)) == 0)
  728. User = FindUser(UT_USER, UserName);
  729. if (!User || (User == INVALID_USER_VALUE) || !FindUser(User, cUserID))
  730. {
  731. LogMsg(LOGF_WARNINGS,"RenameUser(%s) - Can't find the user.", UserName);
  732. return FALSE;
  733. }
  734. UserType = GetType(User);
  735. if (GetParam(User,"Protect",0))
  736. {
  737. LogMsg(LOGF_WARNINGS,"RenameUser(%s) - User is protected.", UserName);
  738. return FALSE;
  739. }
  740. if (FindUser(UserType, NewName))
  741. {
  742. LogMsg(LOGF_WARNINGS,"RenameUser(%s,%s) - New user name exist .", 
  743. UserName, NewName);
  744. return FALSE;
  745. }
  746. //Validiate user name
  747. LPCSTR p = NewName;
  748. while(*p)
  749. {
  750. if (!isalpha(*p) && !isdigit(*p) && !strchr("(){}._-$@#!", *p))
  751. {
  752. LogMsg(LOGF_WARNINGS,"RenameUser(%s,%s) - New user name is illegal .", 
  753. UserName, NewName);
  754. return FALSE;
  755. }
  756. ++p;
  757. }
  758. cBuf.Format("N %d %s", UserType, cUserID);
  759. ::ResetSection(NULL, m_pIniFile, cBuf);
  760. cBuf.Format("N %d %s", UserType, NewName);
  761. ::PutIniItem(NULL, m_pIniFile, cBuf, "UserNum", User);
  762. if (atoi(UserName) || (cUserID == UserName))
  763. {
  764. // Update the user ID unless this is an alias...
  765. SetParam(User, "UserID", NewName);
  766. }
  767. LogMsg(LOGF_SYSTEM,"User %s (%d) is renamed (%s).", cUserID, User, NewName);
  768. return TRUE;
  769. }