source: rtems/cpukit/httpd/um.c @ 391b4dd

4.104.115
Last change on this file since 391b4dd was 391b4dd, checked in by Joel Sherrill <joel.sherrill@…>, on 03/11/10 at 19:12:30

2010-03-11 Joel Sherrill <joel.sherrill@…>

  • ftpd/ftpd.c, httpd/uemf.c, httpd/um.c, httpd/webs.c, httpd/websuemf.c, libblock/src/diskdevs.c, libmisc/capture/capture-cli.c, libmisc/monitor/mon-network.c, libmisc/shell/hexdump-odsyntax.c, libmisc/shell/main_ifconfig.c, libmisc/uuid/parse.c, libnetworking/lib/ftpfs.c, libnetworking/libc/gethostbyht.c, libnetworking/libc/getnetnamadr.c, libnetworking/libc/inet_network.c, libnetworking/rtems/rtems_mii_ioctl.c, score/src/objectgetnameasstring.c: Fix warnings for ctype methods.
  • Property mode set to 100644
File size: 30.2 KB
Line 
1/*
2 *      um.c -- User Management
3 *
4 *      Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
5 *
6 *      See the file "license.txt" for usage and redistribution license requirements
7 *
8 *      $Id$
9 */
10
11/******************************** Description *********************************/
12/*
13 *      User Management routines for adding/deleting/changing users and groups
14 *  Also, routines for determining user access
15 */
16
17/********************************* Includes ***********************************/
18
19#include        "um.h"
20#include        "emfdb.h"
21#include        "webs.h"
22
23/********************************** Defines ***********************************/
24
25#define UM_DB_FILENAME  T("um.xml")
26#define UM_TXT_FILENAME T("umconfig.txt")
27
28/*
29 *      Table names
30 */
31#define UM_USER_TABLENAME       T("users")
32#define UM_GROUP_TABLENAME      T("groups")
33#define UM_ACCESS_TABLENAME     T("access")
34
35/*
36 *      Column names
37 */
38#define UM_NAME                 T("name")
39#define UM_PASS                 T("password")
40#define UM_GROUP                T("group")
41#define UM_PROT                 T("prot")
42#define UM_DISABLE              T("disable")
43#define UM_METHOD               T("method")
44#define UM_PRIVILEGE    T("priv")
45#define UM_SECURE               T("secure")
46
47/*
48 *      XOR encryption mask
49 *              Note:   This string should be modified for individual sites
50 *                              in order to enhance user password security.
51 */
52#define UM_XOR_ENCRYPT  T("*j7a(L#yZ98sSd5HfSgGjMj8;Ss;d)(*&^#@$a2s0i3g")
53
54/******************************** Local Data **********************************/
55
56#ifdef qHierarchicalAccess
57/*
58 * user-provided function to allow hierarchical access protection. See below.
59 * for details.
60 */
61extern bool_t dmfCanAccess(const char_t* usergroup, const char_t* group);
62#endif
63#ifdef UEMF
64/*
65 *      User table definition
66 */
67#define NUMBER_OF_USER_COLUMNS  5
68
69char_t  *userColumnNames[NUMBER_OF_USER_COLUMNS] = {
70                        UM_NAME, UM_PASS, UM_GROUP, UM_PROT, UM_DISABLE
71};
72
73int             userColumnTypes[NUMBER_OF_USER_COLUMNS] = {
74                        T_STRING, T_STRING, T_STRING, T_INT, T_INT
75};
76
77dbTable_t userTable = {
78        UM_USER_TABLENAME,
79        NUMBER_OF_USER_COLUMNS,
80        userColumnNames,
81        userColumnTypes,
82        0,
83        NULL
84};
85
86/*
87 *      Group table definition
88 */
89#define NUMBER_OF_GROUP_COLUMNS 5
90
91char_t  *groupColumnNames[NUMBER_OF_GROUP_COLUMNS] = {
92                        UM_NAME, UM_PRIVILEGE, UM_METHOD, UM_PROT, UM_DISABLE
93};
94
95int             groupColumnTypes[NUMBER_OF_GROUP_COLUMNS] = {
96                        T_STRING, T_INT, T_INT, T_INT, T_INT
97};
98
99dbTable_t groupTable = {
100        UM_GROUP_TABLENAME,
101        NUMBER_OF_GROUP_COLUMNS,
102        groupColumnNames,
103        groupColumnTypes,
104        0,
105        NULL
106};
107
108/*
109 *      Access Limit table definition
110 */
111#define NUMBER_OF_ACCESS_COLUMNS        4
112
113char_t  *accessColumnNames[NUMBER_OF_ACCESS_COLUMNS] = {
114                        UM_NAME, UM_METHOD, UM_SECURE, UM_GROUP
115};
116
117int             accessColumnTypes[NUMBER_OF_ACCESS_COLUMNS] = {
118                        T_STRING, T_INT, T_INT, T_STRING
119};
120
121dbTable_t accessTable = {
122        UM_ACCESS_TABLENAME,
123        NUMBER_OF_ACCESS_COLUMNS,
124        accessColumnNames,
125        accessColumnTypes,
126        0,
127        NULL
128};
129#endif  /* #ifdef UEMF */
130
131/*
132 *      Database Identifier returned from dbOpen()
133 */
134static int              didUM = -1;
135
136/*
137 *      Configuration database persist filename
138 */
139static char_t   *saveFilename = NULL;
140
141static int              umOpenCount = 0;                /* count of apps using this module */
142
143/*************************** Forward Declarations *****************************/
144
145static bool_t umCheckName(char_t *name);
146
147/*********************************** Code *************************************/
148/*
149 *      umOpen() registers the UM tables in the fake emf-database
150 */
151
152int umOpen(void)
153{
154        if (++umOpenCount != 1) {
155                return didUM;
156        }
157/*
158 *      Do not initialize if intialization has already taken place
159 */
160        if (didUM == -1) {
161                didUM = dbOpen(UM_USER_TABLENAME, UM_DB_FILENAME, NULL, 0);
162#ifdef UEMF
163                dbRegisterDBSchema(&userTable);
164                dbRegisterDBSchema(&groupTable);
165                dbRegisterDBSchema(&accessTable);
166#endif
167        }
168
169        if (saveFilename == NULL) {
170                saveFilename = bstrdup(B_L, UM_TXT_FILENAME);
171        }
172
173        return didUM;
174}
175
176/******************************************************************************/
177/*
178 *      umClose() frees up the UM tables in the fake emf-database
179 */
180
181void umClose(void)
182{
183        if (--umOpenCount > 0) {
184                return;
185        }
186/*
187 *      Do not close if intialization has not taken place
188 */
189        if (didUM != -1) {
190                dbClose(didUM);
191                didUM = -1;
192        }
193
194        if (saveFilename != NULL) {
195                bfree(B_L, saveFilename);
196                saveFilename = NULL;
197        }
198}
199
200/******************************************************************************/
201/*
202 *      umCommit() persists all of the UM tables
203 */
204
205int     umCommit(char_t *filename)
206{
207        if (filename && *filename) {
208                if (saveFilename != NULL) {
209                        bfree(B_L, saveFilename);
210                }
211
212                saveFilename = bstrdup(B_L, filename);
213        }
214
215        a_assert (saveFilename && *saveFilename);
216        trace(3, T("UM: Writing User Configuration to file <%s>\n"),
217                saveFilename);
218
219        return dbSave(didUM, saveFilename, 0);
220}
221
222/******************************************************************************/
223/*
224 *      umRestore() loads up the UM tables with persisted data
225 */
226
227int umRestore(char_t *filename)
228{
229        if (filename && *filename) {
230                if (saveFilename != NULL) {
231                        bfree(B_L, saveFilename);
232                }
233
234                saveFilename = bstrdup(B_L, filename);
235        }
236
237        a_assert(saveFilename && *saveFilename);
238
239        trace(3, T("UM: Loading User Configuration from file <%s>\n"),
240                saveFilename);
241
242/*
243 *      First empty the database, otherwise we wind up with duplicates!
244 */
245        dbZero(didUM);
246        return dbLoad(didUM, saveFilename, 0);
247}
248
249/******************************************************************************/
250/*
251 *      Encrypt/Decrypt a text string.
252 *              Returns the number of characters encrypted.
253 */
254
255static int umEncryptString(char_t *textString)
256{
257        char_t  *enMask;
258        unsigned char   enChar;
259        int             numChars;
260
261        a_assert(textString);
262
263        enMask = UM_XOR_ENCRYPT;
264        numChars = 0;
265
266        while (*textString) {
267                enChar = *textString ^ *enMask;
268/*
269 *              Do not produce encrypted text with embedded linefeeds or tabs.
270 *                      Simply use existing character.
271 */
272                if (enChar && !gisspace(enChar))
273                        *textString = enChar;
274/*
275 *              Increment all pointers.
276 */
277                enMask++;
278                textString++;
279                numChars++;
280/*
281 *              Wrap encryption mask pointer if at end of length.
282 */
283                if (*enMask == '\0') {
284                        enMask = UM_XOR_ENCRYPT;
285                }
286        }
287
288        return numChars;
289}
290
291/******************************************************************************/
292/*
293 *      umGetFirstRowData() -   return a pointer to the first non-blank key value
294 *                                                      in the given column for the given table.
295 */
296
297static char_t *umGetFirstRowData(char_t *tableName, char_t *columnName)
298{
299        char_t  *columnData;
300        int             row;
301        int             check;
302
303        a_assert(tableName && *tableName);
304        a_assert(columnName && *columnName);
305
306        row = 0;
307/*
308 *      Move through table until we retrieve the first row with non-null
309 *      column data.
310 */
311        columnData = NULL;
312        while ((check = dbReadStr(didUM, tableName, columnName, row++,
313                &columnData)) == 0 || (check == DB_ERR_ROW_DELETED)) {
314                if (columnData && *columnData) {
315                        return columnData;
316                }
317        }
318
319        return NULL;
320}
321
322/******************************************************************************/
323/*
324 *      umGetNextRowData() -    return a pointer to the first non-blank
325 *                                              key value following the given one.
326 */
327
328static char_t *umGetNextRowData(char_t *tableName, char_t *columnName,
329                                                                char_t *keyLast)
330{
331        char_t  *key;
332        int             row;
333        int             check;
334
335        a_assert(tableName && *tableName);
336        a_assert(columnName && *columnName);
337        a_assert(keyLast && *keyLast);
338/*
339 *      Position row counter to row where the given key value was found
340 */
341        row = 0;
342        key = NULL;
343
344        while ((((check = dbReadStr(didUM, tableName, columnName, row++,
345                &key)) == 0) || (check == DB_ERR_ROW_DELETED)) &&
346                ((key == NULL) || (gstrcmp(key, keyLast) != 0))) {
347        }
348/*
349 *      If the last key value was not found, return NULL
350 */
351        if (!key || gstrcmp(key, keyLast) != 0) {
352                return NULL;
353        }
354/*
355 *      Move through table until we retrieve the next row with a non-null key
356 */
357        while (((check = dbReadStr(didUM, tableName, columnName, row++, &key))
358                == 0) || (check == DB_ERR_ROW_DELETED)) {
359                if (key && *key && (gstrcmp(key, keyLast) != 0)) {
360                        return key;
361                }
362        }
363
364        return NULL;
365}
366
367/******************************************************************************/
368/*
369 *      umAddUser() - Adds a user to the "users" table.
370 */
371
372int     umAddUser(char_t *user, char_t *pass, char_t *group,
373                          bool_t prot, bool_t disabled)
374{
375        int             row;
376        char_t  *password;
377
378        a_assert(user && *user);
379        a_assert(pass && *pass);
380        a_assert(group && *group);
381
382        trace(3, T("UM: Adding User <%s>\n"), user);
383
384/*
385 *      Do not allow duplicates
386 */
387        if (umUserExists(user)) {
388                return UM_ERR_DUPLICATE;
389        }
390
391/*
392 *      Make sure user name and password contain valid characters
393 */
394        if (!umCheckName(user)) {
395                return UM_ERR_BAD_NAME;
396        }
397
398        if (!umCheckName(pass)) {
399                return UM_ERR_BAD_PASSWORD;
400        }
401
402/*
403 *      Make sure group exists
404 */
405        if (!umGroupExists(group)) {
406                return UM_ERR_NOT_FOUND;
407        }
408
409/*
410 *      Now create the user record
411 */
412        row = dbAddRow(didUM, UM_USER_TABLENAME);
413
414        if (row < 0) {
415                return UM_ERR_GENERAL;
416        }
417
418        if (dbWriteStr(didUM, UM_USER_TABLENAME, UM_NAME, row, user) != 0) {
419                return UM_ERR_GENERAL;
420        }
421
422        password = bstrdup(B_L, pass);
423        umEncryptString(password);
424        dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password);
425        bfree(B_L, password);
426        dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group);
427        dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, prot);
428        dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, disabled);
429
430        return 0;
431}
432
433/******************************************************************************/
434/*
435 *      umDeleteUser() - remove a user from the "users" table
436 */
437
438int     umDeleteUser(char_t *user)
439{
440        int row;
441
442        a_assert(user && *user);
443        trace(3, T("UM: Deleting User <%s>\n"), user);
444/*
445 *      Check to see if user is delete-protected
446 */
447        if (umGetUserProtected(user)) {
448                return UM_ERR_PROTECTED;
449        }
450
451/*
452 *      If found, delete the user from the database
453 */
454        if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) >= 0) {
455                return dbDeleteRow(didUM, UM_USER_TABLENAME, row);
456        }
457
458        return UM_ERR_NOT_FOUND;
459}
460
461/******************************************************************************/
462/*
463 *      umGetFirstUser() -      Returns the user ID of the first user found in the
464 *                                              "users" table.
465 */
466
467char_t *umGetFirstUser(void)
468{
469        return umGetFirstRowData(UM_USER_TABLENAME, UM_NAME);
470}
471
472/******************************************************************************/
473/*
474 *      umGetNextUser() Returns the next user found in the "users" table after
475 *                                      the given user.
476 */
477
478char_t *umGetNextUser(char_t *userLast)
479{
480        return umGetNextRowData(UM_USER_TABLENAME, UM_NAME, userLast);
481}
482
483/******************************************************************************/
484/*
485 *      umUserExists()  Returns TRUE if userid exists.
486 */
487
488bool_t umUserExists(char_t *user)
489{
490        a_assert(user && *user);
491
492        if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0) >= 0) {
493                return TRUE;
494        } else {
495                return FALSE;
496        }
497}
498
499/******************************************************************************/
500/*
501 *      umGetUserPassword() returns a de-crypted copy of the user password
502 */
503
504char_t *umGetUserPassword(char_t *user)
505{
506        char_t  *password;
507        int             row;
508
509        a_assert(user && *user);
510
511        password = NULL;
512        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
513
514        if (row >= 0) {
515                char_t *pass = NULL;
516                dbReadStr(didUM, UM_USER_TABLENAME, UM_PASS, row, &pass);
517/*
518 *              Decrypt password
519 *              Note, this function returns a copy of the password, which must
520 *              be deleted at some time in the future.
521 */
522                password = bstrdup(B_L, pass);
523                umEncryptString(password);
524        }
525
526        return password;
527}
528
529/******************************************************************************/
530/*
531 *      umSetUserPassword() updates the user password in the user "table" after
532 *                                              encrypting the given password
533 */
534
535int     umSetUserPassword(char_t *user, char_t *pass)
536{
537        int             row, nRet;
538        char_t  *password;
539
540        a_assert(user && *user);
541        a_assert(pass && *pass);
542        trace(3, T("UM: Attempting to change the password for user <%s>\n"), user);
543/*
544 *      Find the row of the user
545 */
546        if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) < 0) {
547                return UM_ERR_NOT_FOUND;
548        }
549
550        password = bstrdup(B_L, pass);
551        umEncryptString(password);
552        nRet = dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password);
553        bfree(B_L, password);
554
555        return nRet;
556}
557
558/******************************************************************************/
559/*
560 *      umGetUserGroup() returns the name of the user group
561 */
562
563char_t *umGetUserGroup(char_t *user)
564{
565        char_t  *group;
566        int             row;
567
568        a_assert(user && *user);
569        group = NULL;
570/*
571 *      Find the row of the user
572 */
573        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
574
575        if (row >= 0) {
576                dbReadStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, &group);
577        }
578
579        return group;
580}
581
582/******************************************************************************/
583/*
584 *      umSetUserGroup() Sets the name of the user group for the user
585 */
586
587int     umSetUserGroup(char_t *user, char_t *group)
588{
589        int row;
590
591        a_assert(user && *user);
592        a_assert(group && *group);
593/*
594 *      Find the row of the user
595 */
596        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
597
598        if (row >= 0) {
599                return dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group);
600        } else {
601                return UM_ERR_NOT_FOUND;
602        }
603}
604
605/******************************************************************************/
606/*
607 *      umGetUserEnabled() - returns if the user is enabled
608 *      Returns FALSE if the user is not found.
609 */
610
611bool_t  umGetUserEnabled(char_t *user)
612{
613        int disabled, row;
614
615        a_assert(user && *user);
616
617        disabled = 1;
618/*
619 *      Find the row of the user
620 */
621        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
622
623        if (row >= 0) {
624                dbReadInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, &disabled);
625        }
626
627        return (bool_t)!disabled;
628}
629
630/******************************************************************************/
631/*
632 *      umSetUserEnabled() Enables/disables the user
633 */
634int     umSetUserEnabled(char_t *user, bool_t enabled)
635{
636        int row;
637
638        a_assert(user && *user);
639/*
640 *      Find the row of the user
641 */
642        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
643        if (row >= 0) {
644                return dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, !enabled);
645        } else {
646                return UM_ERR_NOT_FOUND;
647        }
648}
649
650/******************************************************************************/
651/*
652 *      umGetUserProtected() - determine deletability of user
653 */
654
655bool_t umGetUserProtected(char_t *user)
656{
657        int protect, row;
658
659        a_assert(user && *user);
660/*
661 *      Find the row of the user
662 */
663        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
664        protect = FALSE;
665
666        if (row >= 0) {
667                dbReadInt(didUM, UM_USER_TABLENAME, UM_PROT, row, &protect);
668        }
669
670        return (bool_t)protect;
671}
672
673/******************************************************************************/
674/*
675 *      umSetUserProtected() sets the delete protection for the user
676 */
677int     umSetUserProtected(char_t *user, bool_t protect)
678{
679        int row;
680
681        a_assert(user && *user);
682/*
683 *      Find the row of the user
684 */
685        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
686
687        if (row >= 0) {
688                return dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, protect);
689        } else {
690                return UM_ERR_NOT_FOUND;
691        }
692}
693
694
695/******************************************************************************/
696/*
697 *      umAddGroup() adds a group to the "Group" table
698 */
699
700int     umAddGroup(char_t *group, short priv, accessMeth_t am,
701                           bool_t prot, bool_t disabled)
702{
703        int row;
704
705        a_assert(group && *group);
706        trace(3, T("UM: Adding group <%s>\n"), group);
707
708/*
709 *      Do not allow duplicates
710 */
711        if (umGroupExists(group)) {
712                return UM_ERR_DUPLICATE;
713        }
714
715/*
716 *      Only allow valid characters in key field
717 */
718        if (!umCheckName(group)) {
719                return UM_ERR_BAD_NAME;
720        }
721
722/*
723 *      Add a new row to the table
724 */
725        if ((row = dbAddRow(didUM, UM_GROUP_TABLENAME)) < 0) {
726                return UM_ERR_GENERAL;
727        }
728
729/*
730 *      Write the key field
731 */
732        if (dbWriteStr(didUM, UM_GROUP_TABLENAME, UM_NAME, row, group) != 0) {
733                return UM_ERR_GENERAL;
734        }
735
736/*
737 *      Write the remaining fields
738 */
739        dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, priv);
740        dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am);
741        dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, prot);
742        dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, disabled);
743
744        return 0;
745}
746
747/******************************************************************************/
748/*
749 *      umDeleteGroup() - Delete a user group, if not protected
750 */
751
752int     umDeleteGroup(char_t *group)
753{
754        int row;
755
756        a_assert(group && *group);
757        trace(3, T("UM: Deleting Group <%s>\n"), group);
758
759/*
760 *      Check to see if the group is in use
761 */
762        if (umGetGroupInUse(group)) {
763                return UM_ERR_IN_USE;
764        }
765
766/*
767 *      Check to see if the group is delete-protected
768 */
769        if (umGetGroupProtected(group)) {
770                return UM_ERR_PROTECTED;
771        }
772
773/*
774 *      Find the row of the group to delete
775 */
776        if ((row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0)) < 0) {
777                return UM_ERR_NOT_FOUND;
778        }
779
780        return dbDeleteRow(didUM, UM_GROUP_TABLENAME, row);
781}
782
783/******************************************************************************/
784/*
785 *      umGroupExists() returns TRUE if group exists, FALSE otherwise
786 */
787
788bool_t umGroupExists(char_t *group)
789{
790        a_assert(group && *group);
791
792        if (dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0) >= 0) {
793                return TRUE;
794        } else {
795                return FALSE;
796        }
797}
798
799
800/******************************************************************************/
801/*
802 *      umGetGroupInUse() returns TRUE if the group is referenced by a user or by
803 *  an access limit.
804 */
805
806bool_t umGetGroupInUse(char_t *group)
807{
808        a_assert(group && *group);
809
810/*
811 *      First, check the user table
812 */
813        if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_GROUP, group, 0) >= 0) {
814                return TRUE;
815        }
816
817/*
818 *      Second, check the access limit table
819 */
820        if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, group, 0) >= 0) {
821                return TRUE;
822        }
823
824        return FALSE;
825}
826
827
828/******************************************************************************/
829/*
830 *      umGetFirstGroup() - return a pointer to the first non-blank group name
831 */
832
833char_t *umGetFirstGroup(void)
834{
835        return umGetFirstRowData(UM_GROUP_TABLENAME, UM_NAME);
836}
837
838/******************************************************************************/
839/*
840 *      umGetNextGroup() -      return a pointer to the first non-blank group name
841 *                                              following the given group name
842 */
843
844char_t *umGetNextGroup(char_t *groupLast)
845{
846        return umGetNextRowData(UM_GROUP_TABLENAME, UM_NAME, groupLast);
847}
848
849/******************************************************************************/
850/*
851 *      Returns the default access method to use for a given group
852 */
853
854accessMeth_t umGetGroupAccessMethod(char_t *group)
855{
856        int am, row;
857
858        a_assert(group && *group);
859        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
860
861        if (row >= 0) {
862                dbReadInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int *)&am);
863        } else {
864                am = AM_INVALID;
865        }
866
867        return (accessMeth_t) am;
868}
869
870/******************************************************************************/
871/*
872 *      Set the default access method to use for a given group
873 */
874
875int     umSetGroupAccessMethod(char_t *group, accessMeth_t am)
876{
877        int row;
878
879        a_assert(group && *group);
880        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
881
882        if (row >= 0) {
883                return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am);
884        } else {
885                return UM_ERR_NOT_FOUND;
886        }
887}
888
889/******************************************************************************/
890/*
891 *      Returns the privilege mask for a given group
892 */
893
894short umGetGroupPrivilege(char_t *group)
895{
896        int privilege, row;
897
898        a_assert(group && *group);
899        privilege = -1;
900        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
901
902        if (row >= 0) {
903                dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, &privilege);
904        }
905
906        return (short) privilege;
907}
908
909/******************************************************************************/
910/*
911 *      Set the privilege mask for a given group
912 */
913
914int     umSetGroupPrivilege(char_t *group, short privilege)
915{
916        int row;
917
918        a_assert(group && *group);
919        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
920
921        if (row >= 0) {
922                return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row,
923                        (int)privilege);
924        } else {
925                return UM_ERR_NOT_FOUND;
926        }
927}
928
929/******************************************************************************/
930/*
931 *      Returns the enabled setting for a given group.
932 *      Returns FALSE if group is not found.
933 */
934
935bool_t umGetGroupEnabled(char_t *group)
936{
937        int disabled, row;
938
939        a_assert(group && *group);
940        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
941        disabled = 1;
942
943        if (row >= 0) {
944                dbReadInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, &disabled);
945        }
946
947        return (bool_t) !disabled;
948}
949
950/******************************************************************************/
951/*
952 *      Sets the enabled setting for a given group.
953 */
954
955int umSetGroupEnabled(char_t *group, bool_t enabled)
956{
957        int row;
958
959        a_assert(group && *group);
960        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
961
962        if (row >= 0) {
963                return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row,
964                        (int) !enabled);
965        } else {
966                return UM_ERR_NOT_FOUND;
967        }
968}
969
970/******************************************************************************/
971/*
972 *      Returns the protected setting for a given group
973 *  Returns FALSE if user is not found
974 */
975
976bool_t umGetGroupProtected(char_t *group)
977{
978        int protect, row;
979
980        a_assert(group && *group);
981
982        protect = 0;
983        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
984        if (row >= 0) {
985                dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, &protect);
986        }
987
988        return (bool_t) protect;
989}
990
991/******************************************************************************/
992/*
993 *      Sets the protected setting for a given group
994 */
995
996int     umSetGroupProtected(char_t *group, bool_t protect)
997{
998        int row;
999
1000        a_assert(group && *group);
1001        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
1002
1003        if (row >= 0) {
1004                return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row,
1005                        (int) protect);
1006        } else {
1007                return UM_ERR_NOT_FOUND;
1008        }
1009}
1010
1011
1012/******************************************************************************/
1013/*
1014 *      umAddAccessLimit() adds an access limit to the "access" table
1015 */
1016
1017int     umAddAccessLimit(char_t *url, accessMeth_t am, short secure, char_t *group)
1018{
1019        int row;
1020
1021        a_assert(url && *url);
1022        trace(3, T("UM: Adding Access Limit for <%s>\n"), url);
1023
1024/*
1025 *      Do not allow duplicates
1026 */
1027        if (umAccessLimitExists(url)) {
1028                return UM_ERR_DUPLICATE;
1029        }
1030
1031/*
1032 *      Add a new row to the table
1033 */
1034        if ((row = dbAddRow(didUM, UM_ACCESS_TABLENAME)) < 0) {
1035                return UM_ERR_GENERAL;
1036        }
1037
1038/*
1039 *      Write the key field
1040 */
1041        if(dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, row, url) < 0) {
1042                return UM_ERR_GENERAL;
1043        }
1044
1045/*
1046 *      Write the remaining fields
1047 */
1048        dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int)am);
1049        dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, (int)secure);
1050        dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group);
1051
1052        return 0;
1053}
1054
1055/******************************************************************************/
1056/*
1057 *      umDeleteAccessLimit()
1058 */
1059
1060int     umDeleteAccessLimit(char_t *url)
1061{
1062        int row;
1063
1064        a_assert(url && *url);
1065        trace(3, T("UM: Deleting Access Limit for <%s>\n"), url);
1066/*
1067 *      Find the row of the access limit to delete
1068 */
1069        if ((row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0)) < 0) {
1070                return UM_ERR_NOT_FOUND;
1071        }
1072
1073        return dbDeleteRow(didUM, UM_ACCESS_TABLENAME, row);
1074}
1075
1076/******************************************************************************/
1077/*
1078 *      umGetFirstGroup() - return a pointer to the first non-blank access limit
1079 */
1080
1081char_t *umGetFirstAccessLimit(void)
1082{
1083        return umGetFirstRowData(UM_ACCESS_TABLENAME, UM_NAME);
1084}
1085
1086/******************************************************************************/
1087/*
1088 *      umGetNextAccessLimit() -        return a pointer to the first non-blank
1089 *                                                              access limit following the given one
1090 */
1091
1092char_t *umGetNextAccessLimit(char_t *urlLast)
1093{
1094        return umGetNextRowData(UM_ACCESS_TABLENAME, UM_NAME, urlLast);
1095}
1096
1097/******************************************************************************/
1098/*
1099 *      umAccessLimitExists() returns TRUE if this access limit exists
1100 */
1101
1102bool_t  umAccessLimitExists(char_t *url)
1103{
1104        a_assert(url && *url);
1105
1106        if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0) < 0) {
1107                return FALSE;
1108        } else {
1109                return TRUE;
1110        }
1111}
1112
1113/******************************************************************************/
1114/*
1115 *      umGetAccessLimit() returns the Access Method for the URL
1116 */
1117
1118accessMeth_t umGetAccessLimitMethod(char_t *url)
1119{
1120        int am, row;
1121
1122        am = (int) AM_INVALID;
1123        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1124
1125        if (row >= 0) {
1126                dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, &am);
1127        }
1128
1129        return (accessMeth_t) am;
1130}
1131
1132/******************************************************************************/
1133/*
1134 *      umSetAccessLimitMethod() - set Access Method for Access Limit
1135 */
1136
1137int     umSetAccessLimitMethod(char_t *url, accessMeth_t am)
1138{
1139        int row;
1140
1141        a_assert(url && *url);
1142        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1143
1144        if (row >= 0) {
1145                return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int) am);
1146        } else {
1147                return UM_ERR_NOT_FOUND;
1148        }
1149}
1150
1151/******************************************************************************/
1152/*
1153 *      umGetAccessLimitSecure() - returns secure switch for access limit
1154 */
1155
1156short umGetAccessLimitSecure(char_t *url)
1157{
1158        int secure, row;
1159
1160        a_assert(url && *url);
1161        secure = -1;
1162        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1163
1164        if (row >= 0) {
1165                dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, &secure);
1166        }
1167
1168        return (short)secure;
1169}
1170
1171/******************************************************************************/
1172/*
1173 *      umSetAccessLimitSecure() - sets the secure flag for the URL
1174 */
1175
1176int     umSetAccessLimitSecure(char_t *url, short secure)
1177{
1178        int row;
1179
1180        a_assert(url && *url);
1181        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1182
1183        if (row >= 0) {
1184                return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row,
1185                        (int)secure);
1186        } else {
1187                return UM_ERR_NOT_FOUND;
1188        }
1189}
1190
1191/******************************************************************************/
1192/*
1193 *      umGetAccessLimitGroup() - returns the user group of the access limit
1194 */
1195
1196char_t *umGetAccessLimitGroup(char_t *url)
1197{
1198        char_t  *group;
1199        int             row;
1200
1201        a_assert(url && *url);
1202        group = NULL;
1203        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1204
1205        if (row >= 0) {
1206                dbReadStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, &group);
1207        }
1208
1209        return group;
1210}
1211
1212/******************************************************************************/
1213/*
1214 *      umSetAccessLimitGroup() - sets the user group for the access limit.
1215 */
1216
1217int     umSetAccessLimitGroup(char_t *url, char_t *group)
1218{
1219        int row;
1220
1221        a_assert(url && *url);
1222        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1223
1224        if (row >= 0) {
1225                return dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group);
1226        } else {
1227                return UM_ERR_NOT_FOUND;
1228        }
1229}
1230
1231/******************************************************************************/
1232/*
1233 *      Returns the access limit to use for a given URL, by checking for URLs up
1234 *      the directory tree.  Creates a new string that must be deleted.
1235 */
1236
1237char_t *umGetAccessLimit(char_t *url)
1238{
1239        char_t  *urlRet, *urlCheck, *lastChar;
1240        int             len;
1241
1242        a_assert(url && *url);
1243        urlRet = NULL;
1244        urlCheck = bstrdup(B_L, url);
1245        a_assert(urlCheck);
1246        len = gstrlen(urlCheck);
1247/*
1248 *      Scan back through URL to see if there is a "parent" access limit
1249 */
1250        while (len && !urlRet) {
1251                if (umAccessLimitExists(urlCheck)) {
1252                        urlRet = bstrdup(B_L, urlCheck);
1253                } else {
1254/*
1255 *      Trim the end portion of the URL to the previous directory marker
1256 */
1257                        lastChar = urlCheck + len;
1258                        lastChar--;
1259
1260                        while ((lastChar >= urlCheck) && ((*lastChar == '/') ||
1261                                (*lastChar == '\\'))) {
1262                                *lastChar = 0;
1263                                lastChar--;
1264                        }
1265
1266                        while ((lastChar >= urlCheck) && (*lastChar != '/') &&
1267                                (*lastChar != '\\')) {
1268                                *lastChar = 0;
1269                                lastChar--;
1270                        }
1271
1272                        len = gstrlen(urlCheck);
1273                }
1274        }
1275        bfree (B_L, urlCheck);
1276
1277        return urlRet;
1278}
1279
1280/******************************************************************************/
1281/*
1282 *      Returns the access method to use for a given URL
1283 */
1284
1285accessMeth_t umGetAccessMethodForURL(char_t *url)
1286{
1287        accessMeth_t    amRet;
1288        char_t                  *urlHavingLimit, *group;
1289
1290        urlHavingLimit = umGetAccessLimit(url);
1291        if (urlHavingLimit) {
1292                group = umGetAccessLimitGroup(urlHavingLimit);
1293
1294                if (group && *group) {
1295                        amRet = umGetGroupAccessMethod(group);
1296                } else {
1297                        amRet = umGetAccessLimitMethod(urlHavingLimit);
1298                }
1299
1300                bfree(B_L, urlHavingLimit);
1301        } else {
1302                amRet = AM_FULL;
1303        }
1304
1305        return amRet;
1306}
1307
1308/******************************************************************************/
1309/*
1310 *      Returns TRUE if user can access URL
1311 */
1312
1313bool_t umUserCanAccessURL(char_t *user, char_t *url)
1314{
1315        accessMeth_t    amURL;
1316        char_t                  *group, *usergroup, *urlHavingLimit;
1317        short                   priv;
1318
1319        a_assert(user && *user);
1320        a_assert(url && *url);
1321
1322/*
1323 *      Make sure user exists
1324 */
1325        if (!umUserExists(user)) {
1326                return FALSE;
1327        }
1328
1329/*
1330 *      Make sure user is enabled
1331 */
1332        if (!umGetUserEnabled(user)) {
1333                return FALSE;
1334        }
1335
1336/*
1337 *      Make sure user has sufficient privileges (any will do)
1338 */
1339        usergroup = umGetUserGroup(user);
1340        priv = umGetGroupPrivilege(usergroup);
1341        if (priv == 0) {
1342                return FALSE;
1343        }
1344
1345/*
1346 *      Make sure user's group is enabled
1347 */
1348        if (!umGetGroupEnabled(usergroup)) {
1349                return FALSE;
1350        }
1351
1352/*
1353 *      The access method of the user group must not be AM_NONE
1354 */
1355        if (umGetGroupAccessMethod(usergroup) == AM_NONE) {
1356                return FALSE;
1357        }
1358
1359/*
1360 *      Check to see if there is an Access Limit for this URL
1361 */
1362        urlHavingLimit = umGetAccessLimit(url);
1363        if (urlHavingLimit) {
1364                amURL = umGetAccessLimitMethod(urlHavingLimit);
1365                group = umGetAccessLimitGroup(urlHavingLimit);
1366                bfree(B_L, urlHavingLimit);
1367        } else {
1368/*
1369 *              If there isn't an access limit for the URL, user has full access
1370 */
1371                return TRUE;
1372        }
1373
1374/*
1375 *      If the access method for the URL is AM_NONE then
1376 *      the file "doesn't exist".
1377 */
1378        if (amURL == AM_NONE) {
1379                return FALSE;
1380        }
1381
1382/*
1383 *      If Access Limit has a group specified, then the user must be a
1384 *      member of that group
1385 */
1386        if (group && *group) {
1387#ifdef qHierarchicalAccess
1388      /*
1389       * If we are compiling with the hierarchical access extensions, we
1390       * instead call the user-provided function that checks to see whether
1391       * the current user's access level is greater than or equal to the
1392       * access level required for this URL.
1393       */
1394      return dmfCanAccess(usergroup, group);
1395
1396#else
1397                if (usergroup && (gstrcmp(group, usergroup) != 0)) {
1398                        return FALSE;
1399
1400                }
1401#endif
1402        }
1403
1404/*
1405 *      Otherwise, user can access the URL
1406 */
1407        return TRUE;
1408
1409}
1410
1411/******************************************************************************/
1412/*
1413 *      Returns TRUE if given name has only valid chars
1414 */
1415
1416static bool_t umCheckName(char_t *name)
1417{
1418        a_assert(name && *name);
1419
1420        if (name && *name) {
1421                while (*name) {
1422                        if (gisspace((int)*name)) {
1423                                return FALSE;
1424                        }
1425
1426                        name++;
1427                }
1428
1429                return TRUE;
1430        }
1431
1432        return FALSE;
1433}
1434
1435/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.