InfiniSQL  v0.1.2-alpha
Massive Scale Transaction Processing
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UserSchemaMgr.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Mark Travis <mtravis15432+src@gmail.com>
3  * All rights reserved. No warranty, explicit or implicit, provided.
4  *
5  * This file is part of InfiniSQL(tm).
6 
7  * InfiniSQL is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 3
9  * as published by the Free Software Foundation.
10  *
11  * InfiniSQL is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with InfiniSQL. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
29 #include "UserSchemaMgr.h"
30 #line 31 "UserSchemaMgr.cc"
31 
32 //UserSchemaMgr::UserSchemaMgr(mboxid_t idarg) : id (idarg) {
34  myIdentity(*myIdentityArg)
35 {
36  delete myIdentityArg;
39 
40  // these are incremented before being given out. domainid 1 is _global
41  nextdomainid = 1;
42 
43  msgsnd = NULL;
44 
45  domainNameToDomainId["_global"] = 1;
48  domainIdToNextUserId[ domainNameToDomainId["_global"] ] = 1;
49  domainIdToUserNames[domainNameToDomainId["_global"]]->operator[]("admin") = 1;
50  domainIdToUserIds[ domainNameToDomainId["_global"] ] =
52  SHA512().CalculateDigest(pwdStruct.digest,
53  (const byte *)myIdentity.argstring.c_str(),
54  myIdentity.argstring.size());
56  myIdentity.argstring.size());
57  domainIdToUserIds[ domainNameToDomainId["_global"] ]->operator[](1) =
58  pwdStruct;
59 
60  fieldTypeMap["int"] = INT;
61  fieldTypeMap["uint"] = UINT;
62  fieldTypeMap["bool"] = BOOL;
63  fieldTypeMap["float"] = FLOAT;
64  fieldTypeMap["char"] = CHAR;
65  fieldTypeMap["charx"] = CHARX;
66  fieldTypeMap["varchar"] = VARCHAR;
67 
68  indexTypeMap["none"] = NONE;
69  indexTypeMap["unique"] = UNIQUE;
70  indexTypeMap["nonunique"] = NONUNIQUE;
71  indexTypeMap["unordered"] = UNORDERED;
72  indexTypeMap["uniquenotnull"] = UNIQUENOTNULL;
73  indexTypeMap["nonuniquenotnull"] = NONUNIQUENOTNULL;
74  indexTypeMap["unorderednotnull"] = UNORDEREDNOTNULL;
75 
76  while (1)
77  {
79  do
80  {
82  }
83  while (msgrcv==NULL);
84 
85  class MessageUserSchema &msgrcvref =
86  *(class MessageUserSchema *)msgrcv;
87 
88  if (msgrcvref.messageStruct.topic != TOPIC_TOPOLOGY &&
90  && msgrcvref.messageStruct.topic != TOPIC_NONE)
91  {
92  argsize = msgrcvref.userschemaStruct.argsize;
96  userid = msgrcvref.userschemaStruct.userid;
97  resultVector = new vector<string>;
98  msgpack2Vector(resultVector, (char *)msgrcvref.argstring.c_str(),
99  argsize);
100  }
101 
102  switch (msgrcv->messageStruct.topic)
103  {
104  case TOPIC_LOGIN:
105  login();
106  break;
107 
109  changepassword();
110  break;
111 
112  case TOPIC_CREATEDOMAIN:
113  createdomain();
114  break;
115 
116  case TOPIC_CREATEUSER:
117  createuser();
118  break;
119 
120  case TOPIC_DELETEUSER:
121  deleteuser();
122  break;
123 
124  case TOPIC_DELETEDOMAIN:
125  deletedomain();
126  break;
127 
128  case TOPIC_SCHEMAREQUEST:
129  switch (msgrcvref.userschemaStruct.builtincmd)
130  {
131  case BUILTINCREATESCHEMA:
132  {
134  }
135  break;
136 
137  case BUILTINCREATETABLE:
139  break;
140 
141  case BUILTINADDCOLUMN:
143  break;
144 
145  case BUILTINDELETEINDEX:
147  break;
148 
149  case BUILTINDELETETABLE:
151  break;
152 
153  case BUILTINDELETESCHEMA:
155  break;
156 
157  default:
158  fprintf(logfile, "UserSchemaMgr bad schema builtin %li\n",
159  msgrcvref.userschemaStruct.builtincmd);
160  }
161 
162  break;
163 
164  case TOPIC_TOPOLOGY:
166  break;
167 
168  case TOPIC_OPERATION:
170  break;
171 
172  default:
173  fprintf(logfile, "UserSchemaMgr bad topic %i\n",
175  }
176 
177  if (msgrcvref.messageStruct.topic != TOPIC_TOPOLOGY &&
178  msgrcvref.messageStruct.topic != TOPIC_OPERATION &&
179  msgrcvref.messageStruct.topic != TOPIC_NONE)
180  {
181  delete resultVector;
182  }
183  }
184 }
185 
187 {
188 }
189 
190 // launcher
191 void *userSchemaMgr(void *identity)
192 {
194  return NULL;
195 }
196 
198 {
199  // vector: 0,1,2: domainname,username,password
201 
203  {
204  class MessageUserSchema *msg =
205  new class MessageUserSchema(TOPIC_LOGINFAIL);
207  return;
208  }
209 
210  int64_t did = domainNameToDomainIdIterator->second;
211  // check username against
213 
215  {
216  class MessageUserSchema *msg =
217  new class MessageUserSchema(TOPIC_LOGINFAIL);
219  return;
220  }
221 
224 
226  {
227  class MessageUserSchema *msg =
228  new class MessageUserSchema(TOPIC_LOGINFAIL);
230  return;
231  }
232 
233  int64_t uid = userNameToUserIdIterator->second;
236 
238  {
239  class MessageUserSchema *msg =
240  new class MessageUserSchema(TOPIC_LOGINFAIL);
242  return;
243  }
244 
246  byte passworddigest[64];
247  SHA512().CalculateDigest(passworddigest,
248  (const byte *)resultVector->at(2).c_str(),
249  resultVector->at(2).length());
250 
251  if (memcmp(pwdStruct.digest, passworddigest, 64))
252  {
253  class MessageUserSchema *msg =
254  new class MessageUserSchema(TOPIC_LOGINFAIL);
256  return;
257  }
258 
259  userid=uid;
260  domainid=did;
261  class MessageUserSchema *msg = new class MessageUserSchema(TOPIC_LOGINOK);
262  msg->domainname=resultVector->at(0);
264 }
265 
267 {
269 
271  {
272  class MessageUserSchema *msg =
273  new class MessageUserSchema(TOPIC_CHANGEPASSWORDFAIL);
274  // replyTa(this, TOPIC_CHANGEPASSWORDFAIL, msg);
276  return;
277  }
278 
280 
282  {
283  class MessageUserSchema *msg =
284  new class MessageUserSchema(TOPIC_CHANGEPASSWORDFAIL);
286  return;
287  }
288 
289  SHA512().CalculateDigest(userIdToPasswordIterator->second.digest,
290  (const byte *)resultVector->at(0).c_str(),
291  resultVector->at(0).length());
292  class MessageUserSchema *msg =
293  new class MessageUserSchema(TOPIC_CHANGEPASSWORDOK);
294  // replyTa(this, TOPIC_CHANGEPASSWORDOK, msg);
296 }
297 
299 {
300  // only _global admin user can do this
301  if (domainid != 1 || userid != 1)
302  {
303  class MessageUserSchema *msg =
304  new class MessageUserSchema(TOPIC_CREATEDOMAINFAIL);
305  // replyTa(this, TOPIC_CREATEDOMAINFAIL, msg);
307  return;
308  }
309 
311 
313  {
314  // domainname exists already
315  class MessageUserSchema *msg =
316  new class MessageUserSchema(TOPIC_CREATEDOMAINFAIL);
317  // replyTa(this, TOPIC_CREATEDOMAINFAIL, msg);
319  return;
320  }
321 
322  int64_t newdomainid = getnextdomainid();
323  // make dname->did & did->usernamemap & did->useridmap & did->nextuserid
324  domainNameToDomainId[resultVector->at(0)] = newdomainid;
325  domainIdToUserNames[newdomainid] = new userNameToUserIdMap;
326  domainIdToUserIds[newdomainid] = new userIdToPasswordMap;
327  domainIdToNextUserId[newdomainid] = 0;
328 
329  domainid = newdomainid;
330  class MessageUserSchema *msg =
331  new class MessageUserSchema(TOPIC_CREATEDOMAINOK);
332  // replyTa(this, TOPIC_CREATEDOMAINOK, msg);
334 }
335 
336 // must be _global admin
338 {
339  if (domainid != 1 || userid != 1)
340  {
341  class MessageUserSchema *msg =
342  new class MessageUserSchema(TOPIC_CREATEUSERFAIL);
343  // replyTa(this, TOPIC_CREATEUSERFAIL, msg);
345  return;
346  }
347 
349 
351  {
352  class MessageUserSchema *msg =
353  new class MessageUserSchema(TOPIC_CREATEUSERFAIL);
354  // replyTa(this, TOPIC_CREATEUSERFAIL, msg);
356  return;
357  }
358 
359  int64_t did = domainNameToDomainIdIterator->second;
361 
363  {
364  // no domainid to usernames entry, so it must have been deleted during
365  // this session
366  class MessageUserSchema *msg =
367  new class MessageUserSchema(TOPIC_CREATEUSERFAIL);
368  // replyTa(this, TOPIC_CREATEUSERFAIL, msg);
370  return;
371  }
372 
373  // check for username already
376 
378  {
379  // username already exists
380  class MessageUserSchema *msg =
381  new class MessageUserSchema(TOPIC_CREATEUSERFAIL);
382  // replyTa(this, TOPIC_CREATEUSERFAIL, msg);
384  return;
385  }
386 
387  /* get next userid, then insert into things
388  * domainIdToUserNames, domainIdToUserIds */
389  int64_t newuserid = getnextuserid(did);
390  userNameToUserId->operator[](resultVector->at(1)) = newuserid;
392  SHA512().CalculateDigest(pwdStruct.digest,
393  (const byte *)resultVector->at(2).c_str(),
394  resultVector->at(2).length());
395  userIdToPassword->operator[](newuserid) = pwdStruct;
396 
397  domainid = did;
398  userid = newuserid;
399  class MessageUserSchema *msg =
400  new class MessageUserSchema(TOPIC_CREATEUSEROK);
402 }
403 
404 // must be _global admin, domainname,username
406 {
407  if (domainid != 1 || userid != 1)
408  {
409  class MessageUserSchema *msg =
410  new class MessageUserSchema(TOPIC_DELETEUSERFAIL);
412  return;
413  }
414 
416 
418  {
419  class MessageUserSchema *msg =
420  new class MessageUserSchema(TOPIC_DELETEUSERFAIL);
421  // replyTa(this, TOPIC_DELETEUSERFAIL, msg);
423  return;
424  }
425 
428 
430  {
431  // no domainid to usernames entry, so it must have been deleted during
432  // this session
433  class MessageUserSchema *msg =
434  new class MessageUserSchema(TOPIC_DELETEUSERFAIL);
435  // replyTa(this, TOPIC_DELETEUSERFAIL, msg);
437  return;
438  }
439 
441 
443  {
444  class MessageUserSchema *msg =
445  new class MessageUserSchema(TOPIC_DELETEUSERFAIL);
447  return;
448  }
449 
451  // check for username already
454 
456  {
457  // username doesn't exist
458  class MessageUserSchema *msg =
459  new class MessageUserSchema(TOPIC_DELETEUSERFAIL);
461  return;
462  }
463 
464  userid = userNameToUserId->at(resultVector->at(1));
465  userNameToUserId->erase(resultVector->at(1));
466 
468 
470  {
471  class MessageUserSchema *msg =
472  new class MessageUserSchema(TOPIC_DELETEUSERFAIL);
474  return;
475  }
476 
478  userIdToPassword->erase(userid);
479 
480  class MessageUserSchema *msg =
481  new class MessageUserSchema(TOPIC_DELETEUSEROK);
483 }
484 
486 {
487  // only _global admin can do this
488  if (domainid != 1 || userid != 1)
489  {
490  class MessageUserSchema *msg =
491  new class MessageUserSchema(TOPIC_DELETEDOMAINFAIL);
492  // replyTa(this, TOPIC_DELETEDOMAINFAIL, msg);
494  return;
495  }
496 
497  /* delete maps, always return ok if name exists. 3 user maps & domain entry
498  * userIdToPassword,userNameToUserId
499  * erase from: domainIdToUserIds, domainIdToUserNames, domainNameToDomainId
500  * domainIdToNextUserId
501  * just need the domainid (by way of the domain name
502  */
504 
506  {
507  class MessageUserSchema *msg =
508  new class MessageUserSchema(TOPIC_DELETEDOMAINFAIL);
510  return;
511  }
512 
514  // assuming that deleting map that isn't there is ok, so no need to check
516  delete domainIdToUserIds[domainid];
520  domainNameToDomainId.erase(resultVector->at(0));
521 
522  class MessageUserSchema *msg =
523  new class MessageUserSchema(TOPIC_DELETEDOMAINOK);
525 }
526 
527 // builtins for schema
529 {
530  switch (cmd)
531  {
532  case STARTCMD:
533  {
534  createSchema(this);
535  class MessageUserSchema *msg =
536  new class MessageUserSchema(TOPIC_SCHEMAREPLY);
538  break;
539  }
540 
541  case ABORTCMD:
542  break;
543 
544  default:
545  fprintf(logfile, "no such cmd %i %s %i\n", cmd, __FILE__, __LINE__);
546  }
547 }
548 
550 {
551  switch (cmd)
552  {
553  case STARTCMD:
554  {
555  class Schema *schemaPtr = NULL;
556  int64_t tid = 0;
557 
558  if (domainidsToSchemata.count(domainid))
559  {
560  schemaPtr = domainidsToSchemata[domainid];
561 
562  // something to check table name exists:
563  if (schemaPtr->tableNameToId.count(resultVector->at(0)))
564  {
565  //table name already exists
567  }
568  else
569  {
570  tid = schemaPtr->getnexttableid();
571  status = schemaPtr->createTable(tid);
572  }
573  }
574  else
575  {
577  }
578 
579  /* either succeeds or fails :-) */
580  // table id & name mapping
581  class MessageUserSchema *msg =
582  new class MessageUserSchema(TOPIC_SCHEMAREPLY);
583  class MessageUserSchema &msgref = *msg;
584 
586  {
587  schemaPtr->tableNameToId[resultVector->at(0)] = tid;
588  msgref.userschemaStruct.tableid = tid;
589 
590  msgref.userschemaStruct.domainid = domainid;
591  msgref.argstring = resultVector->at(0);
592  }
593 
595  }
596  break;
597 
598  case ABORTCMD:
599  break;
600 
601  default:
602  fprintf(logfile, "no such cmd %i %s %i\n", cmd, __FILE__, __LINE__);
603  }
604 }
605 
607 {
608  switch (cmd)
609  {
610  case STARTCMD:
611  {
612  /* either succeeds or fails :-) */
613  // uses domainid, input tableid
614  int64_t tid = boost::lexical_cast<int64_t>(resultVector->at(0));
615  string stringtype = resultVector->at(1);
616  int64_t len = boost::lexical_cast<int64_t>(resultVector->at(2));
617  string name = resultVector->at(3);
618  string stringidxtype = resultVector->at(4);
619  class MessageUserSchema *msg =
620  new class MessageUserSchema(TOPIC_SCHEMAREPLY);
621  class MessageUserSchema &msgref = *msg;
622 
623  if (!fieldTypeMap.count(stringtype))
624  {
625  // map string not found, doh!
628  *msg);
629  return;
630  }
631 
632  fieldtype_e type = fieldTypeMap[stringtype];
633 
634  if (type != CHARX)
635  {
636  len = 0; // zero out the length unless it is charx
637  }
638 
639  if (!indexTypeMap.count(stringidxtype))
640  {
643  *msg);
644  return;
645  }
646 
647  indextype_e idxtype = indexTypeMap[stringidxtype];
648 
649  if (!domainidsToSchemata.count(domainid))
650  {
653  *msg);
654  return;
655  }
656 
657  class Schema *schemaPtr = domainidsToSchemata[domainid];
658 
659  if (!schemaPtr->tables.count(tid))
660  {
663  *msg);
664  return;
665  }
666 
667  class Table *tablePtr = schemaPtr->tables[tid];
668 
669  if (tablePtr->columnaNameToFieldMap.count(name))
670  {
671  // column already exists
674  *msg);
675  return;
676  }
677 
678  msgref.userschemaStruct.fieldid = tablePtr->addfield(type, len, name,
679  idxtype);
680  schemaPtr->fieldNameToId[tid][name] = msgref.userschemaStruct.fieldid;
682  msgref.userschemaStruct.tableid = tid;
683  msgref.userschemaStruct.fieldlen = len;
684  msgref.userschemaStruct.fieldtype = type;
685  msgref.userschemaStruct.indextype = idxtype;
686 
687  msgref.userschemaStruct.domainid = domainid;
688  msgref.argstring = name;
689  msgref.userschemaStruct.argsize = 0;
690 
692  }
693  break;
694 
695  case ABORTCMD:
696  break;
697 
698  default:
699  fprintf(logfile, "no such cmd %i %s %i\n", cmd, __FILE__, __LINE__);
700  }
701 }
702 
704 {
705  switch (cmd)
706  {
707  case STARTCMD:
708  {
709  /* either succeeds or fails :-) */
711  class MessageUserSchema *msg =
712  new class MessageUserSchema(TOPIC_SCHEMAREPLY);
714  }
715  break;
716 
717  case ABORTCMD:
718  break;
719 
720  default:
721  fprintf(logfile, "no such cmd %i %s %i\n", cmd, __FILE__, __LINE__);
722  }
723 }
724 
726 {
727  switch (cmd)
728  {
729  case STARTCMD:
730  {
731  /* either succeeds or fails :-) */
733  class MessageUserSchema *msg =
734  new class MessageUserSchema(TOPIC_SCHEMAREPLY);
736  }
737  break;
738 
739  case ABORTCMD:
740  break;
741 
742  default:
743  fprintf(logfile, "no such cmd %i %s %i\n", cmd, __FILE__, __LINE__);
744  }
745 }
746 
748 {
749  switch (cmd)
750  {
751  case STARTCMD:
752  {
753  /* either succeeds or fails :-) */
755  class MessageUserSchema *msg =
756  new class MessageUserSchema(TOPIC_SCHEMAREPLY);
758  }
759  break;
760 
761  case ABORTCMD:
762  break;
763 
764  default:
765  fprintf(logfile, "no such cmd %i %s %i\n", cmd, __FILE__, __LINE__);
766  }
767 }
768 
770 {
771  return ++nextdomainid;
772 }
773 
774 int64_t UserSchemaMgr::getnextuserid(int64_t argdomainid)
775 {
777 
779  {
780  return -1;
781  }
782 
784  domainIdToNextUserIdIterator->second + 1;
785  return domainIdToNextUserIdIterator->second;
786 }
787 
789 {
790  class MessageUserSchema *replyMsg =
791  new class MessageUserSchema(TOPIC_OPERATION);
792  class MessageUserSchema &replyMsgRef = *replyMsg;
793 
795  {
796  case OPERATION_LOGIN:
797  replyMsgRef.userschemaStruct.status =
798  operationLogin(msgrcvref.username,
799 
800  msgrcvref.domainname, msgrcvref.password,
801  &replyMsgRef.userschemaStruct.userid,
802  &replyMsgRef.userschemaStruct.domainid);
803  replyMsgRef.domainname=msgrcvref.domainname;
804  break;
805 
806  default:
807  printf("%s %i anomaly operationtype %i\n", __FILE__, __LINE__,
808  msgrcvref.userschemaStruct.operationtype);
809  }
810 
811  replyMsgRef.userschemaStruct.operationid =
812  msgrcvref.userschemaStruct.operationid;
813  replyMsgRef.userschemaStruct.caller = msgrcvref.userschemaStruct.caller;
814  replyMsgRef.userschemaStruct.callerstate =
815  msgrcvref.userschemaStruct.callerstate;
817  replyMsgRef);
818 }
819 
821  string &password, int64_t *uid,
822  int64_t *did)
823 {
824  boost::unordered_map<std::string, int64_t>::iterator itDname2Did;
825  boost::unordered_map<int64_t, userNameToUserIdMap *>::iterator itDid2Unames;
826  boost::unordered_map<string, int64_t>::iterator itUname2Uid;
827  boost::unordered_map<int64_t, passwordStruct>::iterator itUid2Password;
828 
829  itDname2Did = domainNameToDomainId.find(domainname);
830 
831  if (itDname2Did == domainNameToDomainId.end())
832  {
833  return STATUS_NOTOK;
834  }
835 
836  *did = itDname2Did->second;
837 
838  itDid2Unames = domainIdToUserNames.find(*did);
839 
840  if (itDid2Unames == domainIdToUserNames.end())
841  {
842  return STATUS_NOTOK;
843  }
844 
845  userNameToUserIdMap &uname2Uid = *itDid2Unames->second;
846 
847  itUname2Uid = uname2Uid.find(username);
848 
849  if (itUname2Uid == uname2Uid.end())
850  {
851  return STATUS_NOTOK;
852  }
853 
854  *uid = itUname2Uid->second;
855 
856  userIdToPasswordMap &uid2Password = *domainIdToUserIds[*did];
857  itUid2Password = uid2Password.find(*uid);
858 
859  if (itUid2Password == uid2Password.end())
860  {
861  return STATUS_NOTOK;
862  }
863 
864  passwordStruct pwd = itUid2Password->second;
865 
866  byte passworddigest[64];
867  SHA512().CalculateDigest(passworddigest, (const byte *)password.c_str(),
868  password.length());
869 
870  if (memcmp(pwdStruct.digest, passworddigest, 64))
871  {
872  return STATUS_NOTOK;
873  }
874 
875  // return vals did & uid have already been set
876  return STATUS_OK;
877 }