home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 May / PCWorld_2002-05_cd.bin / Komunik / sambar / sambar51p.exe / samples / source / LOGIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-17  |  56.4 KB  |  2,278 lines

  1. /*
  2. ** LOGIN
  3. **
  4. **      HTTP Wrapper for the Login/Logout/Profile Management Library
  5. **
  6. **        Confidential Property of Tod Sambar
  7. **        (c) Copyright Tod Sambar 1996-1997
  8. **        All rights reserved.
  9. **
  10. **
  11. ** Public Functions:
  12. **
  13. **        login_init
  14. **        user_login
  15. **        user_logout
  16. **        user_profile
  17. **        user_add
  18. **        user_delete
  19. **        user_update
  20. **        user_passwd
  21. **        user_list
  22. **        user_select
  23. **        user_maillist
  24. **        user_mailbox
  25. **        group_add
  26. **        group_delete
  27. **        group_list
  28. **        group_select
  29. **        ftp_connect
  30. **        mail_connect
  31. **        telnet_connect
  32. **
  33. **
  34. ** History:
  35. ** Chg#    Date    Description                                                Resp
  36. ** ----    -------    -------------------------------------------------------    ----
  37. **         27JAN96    Created                                                    sambar
  38. **         29MAR97    Added user list and update functions                    sambar
  39. **         30MAR97    Added FTP connection security                            sambar
  40. **         10OCT97    Added user password interface                            sambar
  41. **        14NOV97 Added group management                                    sambar
  42. **         28OCT98    Added MAIL connection security                            sambar
  43. */
  44.  
  45. #include    <stdio.h>
  46. #include    <stdlib.h>
  47. #include    <memory.h>
  48. #include    <string.h>
  49. #include    <login.h>
  50.  
  51. #ifndef    WIN32
  52. #include    <string.h>
  53. #else
  54. #include    <direct.h>
  55. #endif    /* WIN32 */
  56.  
  57. /*
  58. ** Login RPC Commands
  59. */
  60. typedef struct login__rpcs
  61. {
  62.     SA_CHAR        *name;
  63.     SA_RPCPARAM    *params;
  64.     SA_INT        numparams;
  65.     SA_INT        auth;
  66.     SA_VOID        *func;
  67.     SA_CHAR        *descr;
  68. } LOGIN__RPCS;
  69.  
  70. static SA_RPCPARAM    adduserp [] =
  71. {
  72.     { "username",     1,    "User login." },
  73.     { "password",     0,    "User password." },
  74.     { "group",         0,    "User group." },
  75.     { "name",         0,    "User name." },
  76.     { "dir",         0,    "Ftp/Document Manager directory of the user." },
  77.     { "makedir",    0,    "Create the user directory." },
  78.     { "ftpprivs",     1,    "Upload priviledges of the user." },
  79.     { "ftpmax",     1,    "FTP/Document Manager maximum upload (MB)." },
  80.     { "mbox",         0,    "Create a mailbox for the user." }
  81. };
  82. static SA_RPCPARAM    upduserp [] =
  83. {
  84.     { "username",     1,    "User login." },
  85.     { "password",     0,    "User password." },
  86.     { "group",         0,    "User group." },
  87.     { "name",         0,    "User name." },
  88.     { "dir",         0,    "Ftp/Document Manager directory of the user." },
  89.     { "ftpprivs",     1,    "Upload priviledges of the user." },
  90.     { "ftpmax",     1,    "FTP/Document Manager maximum upload (MB)." },
  91.     { "mbox",         0,    "Create a mailbox for the user." }
  92. };
  93. static SA_RPCPARAM    deluserp [] =
  94. {
  95.     { "username",     1,    "User login." }
  96. };
  97. static SA_RPCPARAM    userpropp [] =
  98. {
  99.     { "username",     1,    "User login." },
  100.     { "prop",     1,    "User property: group,password,name,dir,ftpprivs,ftpmax" }
  101. };
  102. static SA_RPCPARAM    selectuserp [] =
  103. {
  104.     { "username",     0,    "User login." },
  105. };
  106. static SA_RPCPARAM    addgroupp [] =
  107. {
  108.     { "groupname",     1,    "Symbolic name of the group." }
  109. };
  110. static SA_RPCPARAM    delgroupp [] =
  111. {
  112.     { "groupname",     1,    "Symbolic name of the group." }
  113. };
  114. static SA_RPCPARAM    selectgroupp [] =
  115. {
  116.     { "username",     0,    "User to test against group list." }
  117. };
  118. static SA_RPCPARAM    userpasswdp [] =
  119. {
  120.     { "username",     1,    "User login." },
  121.     { "password",     0,    "Existing password for the user." },
  122.     { "newpasswd",     0,    "New password for the user." },
  123.     { "confpasswd",    0,    "Confirm new password." }
  124. };
  125. static SA_RPCPARAM    usermboxp [] =
  126. {
  127.     { "username",     1,    "User login." },
  128.     { "action",     1,    "Create/Delete user mailbox." }
  129. };
  130.  
  131. static LOGIN__RPCS        login_rpcs [] =
  132. {
  133.     { "adduser",     adduserp,    sizeof(adduserp)/sizeof(SA_RPCPARAM),
  134.        SA_AUTHORIZATION_ADMIN,    (SA_VOID *)user_add,
  135.       "Add a user to the system." },
  136.     { "upduser",     upduserp,    sizeof(upduserp)/sizeof(SA_RPCPARAM),    
  137.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_update,
  138.       "Update a user." }, 
  139.     { "deluser",    deluserp,    sizeof(deluserp)/sizeof(SA_RPCPARAM),     
  140.        SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_delete,
  141.       "Delete a user from the system." },
  142.     { "userprop",    userpropp,    sizeof(userpropp)/sizeof(SA_RPCPARAM),     
  143.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_prop,
  144.       "Get a single user attribute for display." },
  145.     { "listusers",    NULL, 0,
  146.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_list,
  147.       "List users for update/delete." },
  148.     { "selectuser",    selectuserp,sizeof(selectuserp)/sizeof(SA_RPCPARAM),    
  149.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_select,
  150.       "List users for selection in a pick list." },
  151.     { "mailusers",    NULL, 0,
  152.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_maillist,
  153.       "List mail users for update/delete." },
  154.     { "usermbox",    usermboxp,    sizeof(usermboxp)/sizeof(SA_RPCPARAM),    
  155.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_mailbox,
  156.       "Create/Delete a user mailbox." },
  157.  
  158.     { "addgroup",    addgroupp,    sizeof(addgroupp)/sizeof(SA_RPCPARAM),     
  159.       SA_AUTHORIZATION_ADMIN,    (SA_VOID *)group_add,
  160.       "Add a group to the system." },
  161.     { "delgroup",     delgroupp,    sizeof(delgroupp)/sizeof(SA_RPCPARAM),    
  162.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_delete,
  163.       "Delete a group from the system." },
  164.     { "listgroups",    NULL, 0,
  165.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_list,
  166.       "List groups for delete." },
  167.     { "selectgroup",selectgroupp,    sizeof(selectgroupp)/sizeof(SA_RPCPARAM),
  168.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_select,
  169.       "List groups for selection in a pick list." },
  170.  
  171.     { "userpasswd",    userpasswdp,    sizeof(userpasswdp)/sizeof(SA_RPCPARAM),    
  172.       SA_AUTHORIZATION_ALL,        (SA_VOID *)user_passwd,
  173.       "Interface to allow users to change their password." }
  174. };
  175.  
  176. /*
  177. ** Local Prototypes
  178. */
  179. static SA_BOOL     user__inlist(SA_CHAR *list, SA_INT listlen, 
  180.                     SA_CHAR *value, SA_INT valuelen);
  181.  
  182. /*
  183. **  LOGIN_INIT
  184. **
  185. **    Initialize the Login/Logout/Profile Interfaces for use by the 
  186. **    Sambar Server plugins.
  187. **
  188. **
  189. **  Parameters:
  190. **    sactx        Sambar Server context
  191. **
  192. **  Returns:
  193. **    SA_SUCCEED | SA_FAIL
  194. */
  195. SA_RETCODE SA_PUBLIC
  196. login_init(sactx)
  197. SA_CTX        *sactx;
  198. {
  199.     int        i;
  200.  
  201.     /* Register the User RPCs with the server                            */
  202.     for (i = 0; i < sizeof(login_rpcs) / sizeof(LOGIN__RPCS); i++)
  203.     {
  204.         if (sa_cmd_init(sactx, login_rpcs[i].name, login_rpcs[i].params, 
  205.             login_rpcs[i].numparams, login_rpcs[i].auth, login_rpcs[i].descr,
  206.             (SA_RPCFUNC)login_rpcs[i].func) != SA_SUCCEED)
  207.         {
  208.             sa_log2(sactx, SA_LOG_ERROR,
  209.                 "Unable to initialize User Management RPCs");
  210.             return (SA_FAIL);
  211.         } 
  212.     }
  213.  
  214.     sa_log2(sactx, SA_LOG_TRACE, "Login/Logout/Profile Management Initialized");
  215.  
  216.     return (SA_SUCCEED);
  217. }
  218.  
  219. /*
  220. **  USER_LOGIN
  221. **
  222. **    Login a user.  Verify the username/password against the Sambar Server
  223. **    password interfaces.  Store some profile information for use.
  224. **
  225. **  Parameters:
  226. **    sactx            Sambar Server Application context to release.
  227. **    saconn            Sambar Server User Connection handle.
  228. **    username        Name of the user logging in.
  229. **    usernamelen        Length of the user name
  230. **    password        Password of the user logging in.
  231. **    passwordlen        Length of the password.
  232. **    infop            Error return code
  233. **
  234. **  Return Values:
  235. **    SA_SUCCESS | SA_FAIL
  236. */
  237. SA_RETCODE SA_PUBLIC
  238. user_login(sactx, saconn, username, usernamelen, password, passwordlen, infop)
  239. SA_CTX        *sactx;
  240. SA_CONN        *saconn;
  241. SA_CHAR        *username;
  242. SA_INT        usernamelen;
  243. SA_CHAR        *password;
  244. SA_INT        passwordlen;
  245. SA_INT        *infop;
  246. {
  247.     SA_INT                len;
  248.     SA_INT                namelen;
  249.     SA_BOOL                ntauth;
  250.     SA_BOOL                sqlauth;
  251.     SA_BOOL                radiusauth;
  252.     SA_BOOL                status;
  253.     SA_BOOL                usepasswd;
  254.     SA_PASSWD            passwd;
  255.     LOGIN_PROFILE        *profile;
  256.     SA_CHAR                name[62];
  257.     SA_CHAR                buffer[512];
  258.  
  259.     ntauth = 0;
  260.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_NTAUTH, name, 30, 
  261.         (SA_INT *)NULL) == SA_SUCCEED)
  262.     {
  263.         if (stricmp(name, "true") == 0)
  264.             ntauth = 1;
  265.     }
  266.  
  267.     radiusauth = 0;
  268.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_RADIUSAUTH, name, 30, 
  269.         (SA_INT *)NULL) == SA_SUCCEED)
  270.     {
  271.         if (stricmp(name, "true") == 0)
  272.             radiusauth = 1;
  273.     }
  274.  
  275.     sqlauth = 0;
  276.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SQLAUTH, name, 30, 
  277.         (SA_INT *)NULL) == SA_SUCCEED)
  278.     {
  279.         if (stricmp(name, "true") == 0)
  280.             sqlauth = 1;
  281.     }
  282.  
  283.     if (usernamelen == 0)
  284.     {
  285.         *infop = SA_E_INVALIDLOGIN;
  286.         return (SA_FAIL);
  287.     }
  288.  
  289.     usepasswd = 0;
  290.     if ((ntauth) || (radiusauth))
  291.     {
  292.         if ((sa_passwd_verify(sactx, username, usernamelen, password, 
  293.             passwordlen, &status) != SA_SUCCEED) ||
  294.             (!status))
  295.         {
  296.             (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 60,
  297.                 &namelen);
  298.             name[namelen] = '\0';
  299.             sprintf(buffer, 
  300.                 "%sLogin for user '%s' failed - bad password (%s) [host %s]",
  301.                 (radiusauth ? "Radius " : (ntauth ? "NT " : "")),
  302.                 username, password, name);
  303.             sa_log2(sactx, SA_LOG_WARN, buffer);
  304.             *infop = SA_E_INVALIDLOGIN;
  305.             return (SA_FAIL);
  306.         }
  307.  
  308.         /* Lookup the config/password entry for overrides.                */
  309.         if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) 
  310.             == SA_SUCCEED)
  311.         {
  312.             usepasswd = 1;
  313.         }
  314.     }
  315.     else if (sqlauth)
  316.     {
  317.         usepasswd = 1;
  318.         if (sa_passwd_sqlauth(sactx, saconn, username, usernamelen, password, 
  319.             passwordlen, &passwd) != SA_SUCCEED)
  320.         {
  321.             (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 
  322.                 60, &namelen);
  323.             name[namelen] = '\0';
  324.             sprintf(buffer, "SQL Login for user '%s' failed [host %s]", 
  325.                 username, name);
  326.             sa_log2(sactx, SA_LOG_WARN, buffer);
  327.             *infop = SA_E_INVALIDLOGIN;
  328.             return (SA_FAIL);
  329.         }
  330.     }
  331.     else
  332.     {
  333.         usepasswd = 1;
  334.         if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) 
  335.             != SA_SUCCEED)
  336.         {
  337.             (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 
  338.                 60, &namelen);
  339.             name[namelen] = '\0';
  340.             sprintf(buffer, "Login for user '%s' failed [host %s]", 
  341.                 username, name);
  342.             sa_log2(sactx, SA_LOG_WARN, buffer);
  343.             *infop = SA_E_INVALIDLOGIN;
  344.             return (SA_FAIL);
  345.         }
  346.  
  347.         /* Verify the passwords are the same                            */
  348.         if ((passwd.passwordlen != passwordlen) ||
  349.             (strncmp(passwd.password, password, passwordlen) != 0))
  350.         {
  351.             (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 60,
  352.                 &namelen);
  353.             name[namelen] = '\0';
  354.             sprintf(buffer, 
  355.                 "Login for user '%s' failed - bad password (%s) [host %s]",
  356.                 username, password, name);
  357.             sa_log2(sactx, SA_LOG_WARN, buffer);
  358.             *infop = SA_E_INVALIDLOGIN;
  359.             return (SA_FAIL);
  360.         }
  361.     }
  362.  
  363.     /* Allocate and populate a user profile structure                    */
  364.     profile = (LOGIN_PROFILE *)malloc(sizeof(LOGIN_PROFILE));
  365.     if (profile == (LOGIN_PROFILE *)NULL)
  366.     {
  367.         sprintf(buffer, "Login for user '%s' failed - no memory", username);
  368.         sa_log2(sactx, SA_LOG_WARN, buffer);
  369.         *infop = SA_E_INVALIDLOGIN;
  370.         return (SA_FAIL);
  371.     }
  372.  
  373.     memset(profile, 0, sizeof(LOGIN_PROFILE));
  374.     memcpy(profile->name, username, usernamelen);
  375.     profile->name[usernamelen] = '\0';
  376.     memcpy(profile->username, username, usernamelen);
  377.     profile->username[usernamelen] = '\0';
  378.     strcpy(profile->dir, "/");
  379.     strcpy(profile->group, "other");
  380.     profile->privs = SA_PRIV_NOACCESS;
  381.  
  382.     if (usepasswd)
  383.     {
  384.         profile->privs = passwd.privs;
  385.  
  386.         if (passwd.namelen > 0)
  387.         {
  388.             memcpy(profile->name, passwd.name, passwd.namelen);
  389.             profile->name[passwd.namelen] = '\0';
  390.         }
  391.  
  392.         if (passwd.grouplen > 0)
  393.         {
  394.             memcpy(profile->group, passwd.group, passwd.grouplen);
  395.             profile->group[passwd.grouplen] = '\0';
  396.         }
  397.  
  398.         if (passwd.dirlen > 0)
  399.         {
  400.             if (sa_conn_maptourl(saconn, passwd.dir, profile->dir) 
  401.                 != SA_SUCCEED)
  402.             {
  403.                 strcpy(profile->dir, passwd.dir);
  404.             }
  405.  
  406.             /* Strip the trailing slash if found.                        */
  407.             len = strlen(profile->dir);
  408.             if ((len > 1) && (profile->dir[len - 1] == '/'))
  409.                 profile->dir[len - 1] = '\0';
  410.         }
  411.     }
  412.  
  413.     /*
  414.     ** The DAVdir is the WebDAV/Document Manager root directory.
  415.     ** If the user's profile directory is "below" the Document Directory
  416.     ** we map the davdir to the Document Directory "root".
  417.     */
  418.     if (sa_conn_maptodavdir(saconn, profile->dir, profile->davdir) 
  419.         != SA_SUCCEED)
  420.     {
  421.         strcpy(profile->davdir, profile->dir);
  422.     }
  423.  
  424.     /* Load the internal server profile for the user                    */
  425.     (SA_VOID)sa_profile_init(sactx, username, usernamelen, &profile->data);
  426.  
  427.     /* Save the user's root directory for security restrictions         */
  428.     if (sa_conn_props(saconn, SA_SET, SA_CONNPROP_ROOTDIR, profile->dir,
  429.         SA_NULLTERM, (SA_INT *)NULL) != SA_SUCCEED)
  430.     {
  431.         (SA_VOID)free(profile);
  432.         sa_log2(sactx, SA_LOG_ERROR,
  433.             "sa_conn_key(SET, LOGIN_PROFILE_KEY) failed!");
  434.         return (SA_FAIL);
  435.     }
  436.  
  437.     /* Save the user's upload priviledges for security restrictions        */
  438.     if (sa_conn_props(saconn, SA_SET, SA_CONNPROP_PRIVS, 
  439.         (SA_BYTE *)&profile->privs, sizeof(SA_INT), (SA_INT *)NULL) 
  440.         != SA_SUCCEED)
  441.     {
  442.         (SA_VOID)free(profile);
  443.         sa_log2(sactx, SA_LOG_ERROR,
  444.             "sa_conn_key(SET, LOGIN_PROFILE_KEY) failed!");
  445.         return (SA_FAIL);
  446.     }
  447.  
  448.     /* Save the user's profile handle with the user connection            */
  449.     if (sa_conn_key(saconn, SA_SET, LOGIN_PROFILE_KEY, (SA_VOID **)profile)
  450.         != SA_SUCCEED)
  451.     {
  452.         (SA_VOID)free(profile);
  453.         sa_log2(sactx, SA_LOG_ERROR,
  454.             "sa_conn_key(SET, LOGIN_PROFILE_KEY) failed!");
  455.         return (SA_FAIL);
  456.     }
  457.  
  458. #ifdef DEBUG
  459.     (SA_VOID)sa_conn_props(saconn, SA_GET, SA_CONNPROP_HOST, name, 60,
  460.         &namelen);
  461.     name[namelen] = '\0';
  462.     sprintf(buffer, "%sUser '%s' logged in [host %s]", 
  463.         (radiusauth ? "Radius " : (sqlauth ? "SQL " : (ntauth ? "NT " : ""))), 
  464.         username, name);
  465.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  466. #endif    /* DEBUG */
  467.  
  468.     return (SA_SUCCEED);
  469. }
  470.  
  471. /*
  472. **  USER_LOGOUT
  473. **
  474. **    Log out a user.  Free profile resources.
  475. **
  476. **  Parameters:
  477. **    sactx        Sambar Server Application context to release.
  478. **    saconn        Sambar Server User Connection handle.
  479. **
  480. **  Return Values:
  481. **    SA_SUCCESS | SA_FAIL
  482. */
  483. SA_RETCODE SA_PUBLIC
  484. user_logout(sactx, saconn)
  485. SA_CTX        *sactx;
  486. SA_CONN        *saconn;
  487. {
  488.     SA_VOID            *entry;
  489.     LOGIN_PROFILE    *profile;
  490. #ifdef DEBUG
  491.     SA_CHAR            buffer[512];
  492. #endif    /* DEBUG */
  493.  
  494.     /* Get the user's handle from the profile context                    */
  495.     if (sa_conn_key(saconn, SA_GET, LOGIN_PROFILE_KEY, (SA_VOID **)&profile)
  496.         != SA_SUCCEED)
  497.     {
  498.         /* User never completed login                                    */
  499.         return (SA_SUCCEED);
  500.     }
  501.  
  502.     /* Clear the user's profile handle                                    */
  503.     (SA_VOID)sa_conn_key(saconn, SA_CLEAR, LOGIN_PROFILE_KEY, &entry);
  504.  
  505. #ifdef DEBUG
  506.     sprintf(buffer, "User '%s' logged out.", profile->username);
  507.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  508. #endif    /* DEBUG */
  509.  
  510.     if (profile->data != (SA_PROFILE *)NULL)
  511.     {
  512.         (SA_VOID)sa_profile_save(sactx, profile->data);
  513.         (SA_VOID)sa_profile_exit(sactx, profile->data);
  514.     }
  515.  
  516.     (void)free(profile);
  517.  
  518.     return (SA_SUCCEED);
  519. }
  520.  
  521. /*
  522. **  USER_PROFILE
  523. **
  524. **    Respond to a user profile request.
  525. **
  526. **  Parameters:
  527. **    sactx        Sambar Server Application context to release.
  528. **    saconn        Sambar Server User Connection handle.
  529. **    buffer        Profile attribute being queried.
  530. **    buflen        Length of the profile attribute.
  531. **    data        Buffer for the profile result 
  532. **                Note: A maximum of 512 bytes may be written to the data buffer.
  533. **
  534. **  Return Values:
  535. **    SA_SUCCESS | SA_FAIL
  536. */
  537. SA_RETCODE SA_PUBLIC
  538. user_profile(sactx, saconn, action, name, namelen, datap)
  539. SA_CTX        *sactx;
  540. SA_CONN        *saconn;
  541. SA_INT        action;
  542. SA_CHAR        *name;
  543. SA_INT        namelen;
  544. SA_VOID        *datap;
  545. {
  546.     LOGIN_PROFILE    *profile;
  547.     SA_CHAR            tmp[512];
  548.  
  549.     /* Get the user's profile handle                                     */
  550.     if (sa_conn_key(saconn, SA_GET, LOGIN_PROFILE_KEY, (SA_VOID **)&profile)
  551.         != SA_SUCCEED)
  552.     {
  553.         /* User never completed login                                    */
  554.         return (SA_FAIL);
  555.     }
  556.  
  557.     if (profile == (LOGIN_PROFILE *)NULL)
  558.     {
  559.         sa_log2(sactx, SA_LOG_ERROR,
  560.             "user_profile:  LOGIN_PROFILE_KEY returned NULL!");
  561.         return (SA_FAIL);
  562.     }
  563.  
  564.     if (profile->data == (SA_PROFILE *)NULL)
  565.     {
  566.         sprintf(tmp, "user_profile:  SA_PROFILE returned NULL for user %s!",
  567.             profile->name);
  568.         sa_log2(sactx, SA_LOG_ERROR, tmp);
  569.         return (SA_FAIL);
  570.     }
  571.  
  572.     /* 
  573.     ** Profile lookup
  574.     */
  575.     if (action == SA_GET)
  576.     {
  577.         if ((namelen == 5) && (strncmp(name, "group", 5) == 0))
  578.         {
  579.             *((SA_CHAR **)datap) = profile->group;
  580.         }
  581.         else if ((namelen == 4) && (strncmp(name, "name", 4) == 0))
  582.         {
  583.             *((SA_CHAR **)datap) = profile->name;
  584.         }
  585.         else if ((namelen == 8) && (strncmp(name, "username", 8) == 0))
  586.         {
  587.             *((SA_CHAR **)datap) = profile->username;
  588.         }
  589.         else if ((namelen == 3) && (strncmp(name, "dir", 3) == 0))
  590.         {
  591.             *((SA_CHAR **)datap) = profile->dir;
  592.         }
  593.         else if ((namelen == 6) && (strncmp(name, "davdir", 6) == 0))
  594.         {
  595.             *((SA_CHAR **)datap) = profile->davdir;
  596.         }
  597.         else
  598.         {
  599.             if (sa_profile_get(sactx, profile->data, name, namelen, 
  600.                 (SA_CHAR **)datap) != SA_SUCCEED)
  601.             {
  602. #ifdef    DEBUG
  603.                 sprintf(tmp, "Profile attribute '%s' not found!", name);
  604.                 sa_log2(sactx, SA_LOG_WARN, tmp);
  605. #endif    /* DEBUG */
  606.                 return (SA_FAIL);
  607.             }
  608.         }
  609.     }
  610.     else
  611.     {
  612.         if (sa_profile_set(sactx, profile->data, name, namelen, 
  613.             (SA_CHAR *)datap) != SA_SUCCEED)
  614.         {
  615.             sprintf(tmp, "Profile attribute '%s' could not be set!", name);
  616.             sa_log2(sactx, SA_LOG_WARN, tmp);
  617.             return (SA_FAIL);
  618.         }
  619.     }
  620.  
  621.     return (SA_SUCCEED);
  622. }
  623.  
  624. /*
  625. **  USER_ADD
  626. **
  627. **    Add a new user
  628. **
  629. **  Parameters:
  630. **    sactx        Sambar Server context
  631. **    saconn        Sambar Server connection
  632. **    saparams    RPC Parameters
  633. **    infop        Error parameters
  634. **
  635. **  Returns:
  636. **    SA_SUCCEED | SA_FAIL
  637. */
  638. SA_RETCODE SA_PUBLIC
  639. user_add(sactx, saconn, saparams, infop)
  640. SA_CTX        *sactx;
  641. SA_CONN        *saconn;
  642. SA_PARAMS    *saparams;
  643. SA_INT        *infop;
  644. {
  645.     SA_INT        mbox;
  646.     SA_INT        datalen;
  647.     SA_INT        makedir;
  648.     SA_CHAR        *data;
  649.     SA_CHAR        path[1024];
  650.     SA_PASSWD    passwd;
  651.     SA_PASSWD    tmppasswd;
  652.  
  653.     memset(&passwd, 0, sizeof(SA_PASSWD));
  654.     
  655.     mbox = 0;
  656.     if (sa_param(sactx, saparams, "mbox", &data, &datalen) == SA_SUCCEED)
  657.     {
  658.         if ((datalen == 2) && (stricmp(data, "on") == 0))
  659.             mbox = 1;
  660.     }
  661.     
  662.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  663.     {
  664.         *infop = SA_E_INVALIDDATA;
  665.         sa_log2(sactx, SA_LOG_WARN, 
  666.             "user_add(): Expected parameter 'password'!");
  667.         return (SA_FAIL);
  668.     }
  669.     
  670.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  671.     if (passwd.passwordlen > 0)
  672.         memcpy(passwd.password, data, passwd.passwordlen);
  673.  
  674.     if (sa_param(sactx, saparams, "group", &data, &datalen) != SA_SUCCEED)
  675.     {
  676.         *infop = SA_E_INVALIDDATA;
  677.         sa_log2(sactx, SA_LOG_WARN, "user_add(): Expected parameter 'group'!");
  678.         return (SA_FAIL);
  679.     }
  680.     
  681.     passwd.grouplen = MIN(datalen, SA_MAX_NAME);
  682.     if (passwd.grouplen > 0)
  683.         memcpy(passwd.group, data, passwd.grouplen);
  684.  
  685.     if (sa_param(sactx, saparams, "name", &data, &datalen) != SA_SUCCEED)
  686.     {
  687.         *infop = SA_E_INVALIDDATA;
  688.         sa_log2(sactx, SA_LOG_WARN, "user_add(): Expected parameter 'name'!");
  689.         return (SA_FAIL);
  690.     }
  691.     
  692.     passwd.namelen = MIN(datalen, SA_MAX_NAME);
  693.     if (passwd.namelen > 0)
  694.         memcpy(passwd.name, data, passwd.namelen);
  695.  
  696.     makedir = 0;
  697.     if (sa_param(sactx, saparams, "makedir", &data, &datalen) == SA_SUCCEED)
  698.     {
  699.         if ((datalen == 4) && (strcmp(data, "true") == 0))
  700.             makedir = 1;
  701.     }
  702.  
  703.     if (sa_param(sactx, saparams, "dir", &data, &datalen) != SA_SUCCEED)
  704.     {
  705.         *infop = SA_E_INVALIDDATA;
  706.         sa_log2(sactx, SA_LOG_WARN, "user_add(): Expected parameter 'dir'!");
  707.         return (SA_FAIL);
  708.     }
  709.     
  710.     passwd.dirlen = MIN(datalen, SA_MAX_NAME);
  711.     if (passwd.dirlen > 0)
  712.         memcpy(passwd.dir, data, passwd.dirlen);
  713.  
  714.     if (sa_param(sactx, saparams, "ftpprivs", &data, &datalen) != SA_SUCCEED)
  715.     {
  716.         *infop = SA_E_INVALIDDATA;
  717.         sa_log2(sactx, SA_LOG_WARN, 
  718.             "user_add(): Expected parameter 'ftpprivs'!");
  719.         return (SA_FAIL);
  720.     }
  721.  
  722.     if (datalen < 12)
  723.         passwd.privs = atol(data);
  724.     
  725.     if (sa_param(sactx, saparams, "ftpmax", &data, &datalen) != SA_SUCCEED)
  726.     {
  727.         *infop = SA_E_INVALIDDATA;
  728.         sa_log2(sactx, SA_LOG_WARN,
  729.             "user_add(): Expected parameter 'ftpmax'!");
  730.         return (SA_FAIL);
  731.     }
  732.     
  733.     if (datalen < 12)
  734.         passwd.ftpmax = atol(data);
  735.     if (passwd.ftpmax < 5)
  736.         passwd.ftpmax = 0;
  737.  
  738.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  739.     {
  740.         *infop = SA_E_INVALIDDATA;
  741.         sa_log2(sactx, SA_LOG_WARN,
  742.             "user_add(): Expected parameter 'username'!");
  743.         return (SA_FAIL);
  744.     }
  745.  
  746.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  747.     {
  748.         *infop = SA_E_INVALIDDATA;
  749.         sa_log2(sactx, SA_LOG_WARN, "user_add(): 'username' field left NULL!");
  750.         return (SA_FAIL);
  751.     }
  752.  
  753.     /* Does the user already exist?                                        */
  754.     if (sa_passwd_lookup(sactx, data, datalen, &tmppasswd) == SA_SUCCEED)
  755.     {
  756.         *infop = SA_E_ALREADYDEFINED;
  757.         return (SA_FAIL);
  758.     }
  759.  
  760.     /* Create the user account.                                            */
  761.     if (sa_passwd_add(sactx, data, datalen, &passwd) != SA_SUCCEED)
  762.     {
  763.         *infop = SA_E_INTERNALSYSTEM;
  764.         sa_log2(sactx, SA_LOG_ERROR, "user_add(): sa_passwd_add() failed!");
  765.         return (SA_FAIL);
  766.     }
  767.  
  768.     /* Create the user mailbox.                                            */
  769.     if (mbox)
  770.     {
  771.         if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  772.         {
  773.             *infop = SA_E_ALREADYDEFINED;
  774.             sa_log2(sactx, SA_LOG_ERROR, "user_add(): sa_mbox_create() failed!");
  775.             return (SA_FAIL);
  776.         }
  777.     }
  778.  
  779.     /* Create the user directory                                        */
  780.     if ((makedir) && (passwd.dirlen > 0))
  781.     {
  782.         if (sa_get_userpath(sactx, saconn, passwd.dir, path, 1000) 
  783.             == SA_SUCCEED)
  784.         {
  785. #ifdef WIN32
  786.             (void)mkdir(path);
  787. #else
  788.             (void)mkdir(path, 733);
  789. #endif
  790.         }
  791.     }
  792.  
  793.     return (SA_SUCCEED);
  794. }
  795.  
  796. /*
  797. **  USER_UPDATE
  798. **
  799. **    Update an existing user
  800. **
  801. **  Parameters:
  802. **    sactx        Sambar Server context
  803. **    saconn        Sambar Server connection
  804. **    saparams    RPC Parameters
  805. **    infop        Error parameters
  806. **
  807. **  Returns:
  808. **    SA_SUCCEED | SA_FAIL
  809. */
  810. SA_RETCODE SA_PUBLIC
  811. user_update(sactx, saconn, saparams, infop)
  812. SA_CTX        *sactx;
  813. SA_CONN        *saconn;
  814. SA_PARAMS    *saparams;
  815. SA_INT        *infop;
  816. {
  817.     SA_INT        mbox;
  818.     SA_INT        datalen;
  819.     SA_CHAR        *data;
  820.     SA_PASSWD    passwd;
  821.  
  822.     memset(&passwd, 0, sizeof(SA_PASSWD));
  823.  
  824.     mbox = 0;
  825.     if (sa_param(sactx, saparams, "mbox", &data, &datalen) == SA_SUCCEED)
  826.     {
  827.         if ((datalen == 2) && (stricmp(data, "on") == 0))
  828.             mbox = 1;
  829.     }
  830.     
  831.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  832.     {
  833.         *infop = SA_E_INVALIDDATA;
  834.         sa_log2(sactx, SA_LOG_WARN,
  835.             "user_update(): Expected parameter 'password'!");
  836.         return (SA_FAIL);
  837.     }
  838.     
  839.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  840.     if (passwd.passwordlen > 0)
  841.         memcpy(passwd.password, data, passwd.passwordlen);
  842.  
  843.     if (sa_param(sactx, saparams, "group", &data, &datalen) != SA_SUCCEED)
  844.     {
  845.         *infop = SA_E_INVALIDDATA;
  846.         sa_log2(sactx, SA_LOG_WARN,
  847.             "user_update(): Expected parameter 'group'!");
  848.         return (SA_FAIL);
  849.     }
  850.     
  851.     passwd.grouplen = MIN(datalen, SA_MAX_NAME);
  852.     if (passwd.grouplen > 0)
  853.         memcpy(passwd.group, data, passwd.grouplen);
  854.  
  855.     if (sa_param(sactx, saparams, "name", &data, &datalen) != SA_SUCCEED)
  856.     {
  857.         *infop = SA_E_INVALIDDATA;
  858.         sa_log2(sactx, SA_LOG_WARN, "user_update(): Expected parameter 'name'!");
  859.         return (SA_FAIL);
  860.     }
  861.     
  862.     passwd.namelen = MIN(datalen, SA_MAX_NAME);
  863.     if (passwd.namelen > 0)
  864.         memcpy(passwd.name, data, passwd.namelen);
  865.  
  866.     if (sa_param(sactx, saparams, "dir", &data, &datalen) != SA_SUCCEED)
  867.     {
  868.         *infop = SA_E_INVALIDDATA;
  869.         sa_log2(sactx, SA_LOG_WARN, "user_update(): Expected parameter 'dir'!");
  870.         return (SA_FAIL);
  871.     }
  872.     
  873.     passwd.dirlen = MIN(datalen, SA_MAX_NAME);
  874.     if (passwd.dirlen > 0)
  875.         memcpy(passwd.dir, data, passwd.dirlen);
  876.  
  877.     if (sa_param(sactx, saparams, "ftpprivs", &data, &datalen) != SA_SUCCEED)
  878.     {
  879.         *infop = SA_E_INVALIDDATA;
  880.         sa_log2(sactx, SA_LOG_WARN, 
  881.             "user_update(): Expected parameter 'ftpprivs'!");
  882.         return (SA_FAIL);
  883.     }
  884.     
  885.     if (datalen < 12)
  886.         passwd.privs = atol(data);
  887.  
  888.     if (sa_param(sactx, saparams, "ftpmax", &data, &datalen) != SA_SUCCEED)
  889.     {
  890.         *infop = SA_E_INVALIDDATA;
  891.         sa_log2(sactx, SA_LOG_WARN, 
  892.             "user_update(): Expected parameter 'ftpmax'!");
  893.         return (SA_FAIL);
  894.     }
  895.     
  896.     if (datalen < 12)
  897.         passwd.ftpmax = atol(data);
  898.     if (passwd.ftpmax < 5)
  899.         passwd.ftpmax = 0;
  900.  
  901.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  902.     {
  903.         *infop = SA_E_INVALIDDATA;
  904.         sa_log2(sactx, SA_LOG_WARN, 
  905.             "user_update(): Expected parameter 'username'!");
  906.         return (SA_FAIL);
  907.     }
  908.  
  909.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  910.     {
  911.         *infop = SA_E_INVALIDDATA;
  912.         sa_log2(sactx, SA_LOG_WARN, 
  913.             "user_update(): 'username' field left NULL!");
  914.         return (SA_FAIL);
  915.     }
  916.  
  917.     if (sa_passwd_update(sactx, data, datalen, &passwd) != SA_SUCCEED)
  918.     {
  919.         *infop = SA_E_ALREADYDEFINED;
  920.         sa_log2(sactx, SA_LOG_ERROR, 
  921.             "user_update(): sa_passwd_update() failed!");
  922.         return (SA_FAIL);
  923.     }
  924.  
  925.     /* Create the user mailbox.                                            */
  926.     if (mbox)
  927.     {
  928.         if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  929.         {
  930.             *infop = SA_E_ALREADYDEFINED;
  931.             sa_log2(sactx, SA_LOG_ERROR,
  932.                 "user_update(): sa_mbox_create() failed!");
  933.             return (SA_FAIL);
  934.         }
  935.     }
  936.  
  937.     return (SA_SUCCEED);
  938. }
  939.  
  940. /*
  941. **  USER_DELETE
  942. **
  943. **    Delete an existing user
  944. **
  945. **  Parameters:
  946. **    sactx        Sambar Server context
  947. **    saconn        Sambar Server connection
  948. **    saparams    RPC Parameters
  949. **    infop        Error parameters
  950. **
  951. **  Returns:
  952. **    SA_SUCCEED | SA_FAIL
  953. */
  954. SA_RETCODE SA_PUBLIC
  955. user_delete(sactx, saconn, saparams, infop)
  956. SA_CTX        *sactx;
  957. SA_CONN        *saconn;
  958. SA_PARAMS    *saparams;
  959. SA_INT        *infop;
  960. {
  961.     SA_INT        datalen;
  962.     SA_INT        sysadminlen;
  963.     SA_CHAR        *data;
  964.     SA_CHAR        sysadmin[1024];
  965.  
  966.     /* Get the sysadmin user (disallow deletes)                            */
  967.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SYSADMIN, (SA_BYTE *)sysadmin,
  968.         1000, &sysadminlen) != SA_SUCCEED)
  969.     {
  970.         sa_log2(sactx, SA_LOG_ERROR,
  971.             "user_delete(): failure retrieving system admin user!");
  972.         return (SA_FAIL);
  973.     }
  974.  
  975.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  976.     {
  977.         *infop = SA_E_INVALIDDATA;
  978.         sa_log2(sactx, SA_LOG_WARN,
  979.             "user_delete(): Expected parameter 'username'!");
  980.         return (SA_FAIL);
  981.     }
  982.  
  983.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  984.     {
  985.         *infop = SA_E_INVALIDDATA;
  986.         sa_log2(sactx, SA_LOG_WARN,
  987.             "user_delete(): 'username' field left NULL!");
  988.         return (SA_FAIL);
  989.     }
  990.  
  991.     /* Don't allow the deletion of the system administrator                */
  992.     if (!user__inlist(data, datalen, sysadmin, sysadminlen))
  993.     {
  994.         (SA_VOID)sa_passwd_delete(sactx, data, datalen);
  995.         (SA_VOID)sa_mbox_delete(sactx, data);
  996.     }
  997.  
  998.     return (SA_SUCCEED);
  999. }
  1000.  
  1001. /*
  1002. **  USER_SELECT
  1003. **
  1004. **    List all users for selection.
  1005. **
  1006. **  Parameters:
  1007. **    sactx        Sambar Server context
  1008. **    saconn        Sambar Server connection
  1009. **    saparams    RPC Parameters
  1010. **    infop        Error parameters
  1011. **
  1012. **  Returns:
  1013. **    SA_SUCCEED | SA_FAIL
  1014. **
  1015. **  Notes:
  1016. **    This list is truncated at 500 names.
  1017. */
  1018. SA_RETCODE SA_PUBLIC
  1019. user_select(sactx, saconn, saparams, infop)
  1020. SA_CTX        *sactx;
  1021. SA_CONN        *saconn;
  1022. SA_PARAMS    *saparams;
  1023. SA_INT        *infop;
  1024. {
  1025.     SA_INT            i;
  1026.     SA_BOOL            selected;
  1027.     SA_INT            usernamelen;
  1028.     SA_INT            numusers;
  1029.     SA_CHAR            *username;
  1030.     SA_USER            users[500];
  1031.     SA_CHAR            buffer[512];
  1032.  
  1033.     /* If a username is provided make it SELECTED in the OPTION list    */
  1034.     (SA_VOID)sa_param(sactx, saparams, "username", &username, &usernamelen);
  1035.  
  1036.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  1037.     {
  1038.         sa_log2(sactx, SA_LOG_ERROR,
  1039.             "user_select(): failure retrieving names list!");
  1040.         return (SA_FAIL);
  1041.     }
  1042.  
  1043.     /* Display the list of users.                                        */
  1044.     for (i = 0; i < numusers; i++)
  1045.     {
  1046.         selected = 0;
  1047.         if ((users[i].usernamelen == usernamelen) &&
  1048.             (memcmp(username, users[i].username, usernamelen) == 0))
  1049.         {
  1050.             selected = 1;
  1051.         }
  1052.  
  1053.         sprintf(buffer, "<OPTION %s>%s\n", (selected ? "SELECTED" : ""),
  1054.                 users[i].username);
  1055.  
  1056.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1057.             return (SA_FAIL);
  1058.     }
  1059.  
  1060.     return (SA_SUCCEED);
  1061. }
  1062.  
  1063. /*
  1064. **  USER_LIST
  1065. **
  1066. **    List all users for delete or update.
  1067. **
  1068. **  Parameters:
  1069. **    sactx        Sambar Server context
  1070. **    saconn        Sambar Server connection
  1071. **    saparams    RPC Parameters
  1072. **    infop        Error parameters
  1073. **
  1074. **  Returns:
  1075. **    SA_SUCCEED | SA_FAIL
  1076. **
  1077. **  Notes:
  1078. **    This list is truncated at 500 names.
  1079. **    List users by group...
  1080. */
  1081. SA_RETCODE SA_PUBLIC
  1082. user_list(sactx, saconn, saparams, infop)
  1083. SA_CTX        *sactx;
  1084. SA_CONN        *saconn;
  1085. SA_PARAMS    *saparams;
  1086. SA_INT        *infop;
  1087. {
  1088.     SA_INT            i;
  1089.     SA_INT            j;
  1090.     SA_INT            sysadminlen;
  1091.     SA_INT            numusers;
  1092.     SA_INT            numgroups;
  1093.     SA_GROUP        groups[100];
  1094.     SA_USER            users[500];
  1095.     SA_CHAR            sysadmin[1024];
  1096.     SA_CHAR            buffer[512];
  1097.  
  1098.     /* Get the sysadmin user (disallow deletes)                            */
  1099.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SYSADMIN, (SA_BYTE *)sysadmin,
  1100.         1000, &sysadminlen) != SA_SUCCEED)
  1101.     {
  1102.         sa_log2(sactx, SA_LOG_ERROR,
  1103.             "user_list(): failure retrieving system admin user!");
  1104.         return (SA_FAIL);
  1105.     }
  1106.  
  1107.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  1108.     {
  1109.         sa_log2(sactx, SA_LOG_ERROR,
  1110.             "user_list(): failure retrieving names list!");
  1111.         return (SA_FAIL);
  1112.     }
  1113.  
  1114.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  1115.     {
  1116.         sa_log2(sactx, SA_LOG_ERROR,
  1117.             "user_list(): failure retrieving groups list!");
  1118.         return (SA_FAIL);
  1119.     }
  1120.  
  1121.     /*
  1122.     ** Display the users by "group".
  1123.     ** Zero the usernamelen after displaying so we can put the rest in
  1124.     ** the "other" list.
  1125.     */
  1126.     for (j = 0; j < numgroups; j++)
  1127.     {
  1128.         sprintf(buffer, "<FONT SIZE=+1 COLOR=#990033>%s</FONT><BLOCKQUOTE>\n",
  1129.             groups[j].name);
  1130.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1131.             return (SA_FAIL);
  1132.         
  1133.         /* Display the users in that group.                                */
  1134.         for (i = 0; i < numusers; i++)
  1135.         {
  1136.             if ((users[i].usernamelen > 0) && 
  1137.                 (users[i].grouplen == groups[j].namelen) &&
  1138.                 (memcmp(users[i].group, groups[j].name, users[i].grouplen)==0))
  1139.             {
  1140.                 /* Make sure we don't display the user twice.            */
  1141.                 users[i].usernamelen = 0;
  1142.  
  1143.                 if (!user__inlist(users[i].username, users[i].usernamelen, 
  1144.                     sysadmin, sysadminlen))
  1145.                 {
  1146.                     sprintf(buffer, 
  1147.                         "<A HREF=\"/session/deluser?username=%s&RCpage=/sysadmin/usermgmt/userlist.stm\" onClick=\"return confirmDelete()\"><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/trash.gif\"></A>\n",
  1148.                         users[i].username);
  1149.  
  1150.                     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1151.                         return (SA_FAIL);
  1152.                 }
  1153.  
  1154.                 sprintf(buffer, 
  1155.                     "<A HREF=\"/sysadmin/usermgmt/upduser.stm?RCSusername=%s\" TARGET=body><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/info.gif\"> %s</A><BR>\n",
  1156.                     users[i].username, users[i].username);
  1157.  
  1158.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1159.                     return (SA_FAIL);
  1160.             }
  1161.         }
  1162.  
  1163.         if (sa_conn_send(saconn, "</BLOCKQUOTE>", SA_NULLTERM) != SA_SUCCEED)
  1164.             return (SA_FAIL);
  1165.     }
  1166.  
  1167.     /* Display the "other" group                                        */
  1168.     sprintf(buffer, "<FONT SIZE=+1 COLOR=#990066>%s</FONT><BLOCKQUOTE>\n", 
  1169.         SA_DEFAULT_GROUP);
  1170.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1171.         return (SA_FAIL);
  1172.         
  1173.     /* Display the users in that group.                                    */
  1174.     for (i = 0; i < numusers; i++)
  1175.     {
  1176.         /* Display all users not in any other group.                    */
  1177.         if (users[i].usernamelen > 0)
  1178.         {
  1179.             if (!user__inlist(users[i].username, users[i].usernamelen, 
  1180.                 sysadmin, sysadminlen))
  1181.             {
  1182.                 sprintf(buffer, 
  1183.                     "<A HREF=\"/session/deluser?username=%s&RCpage=/sysadmin/usermgmt/userlist.stm\" onClick=\"return confirmDelete()\"><IMG border=0 HEIGHT=15 WIDTH=15 SRC=\"/sysimage/system/trash.gif\"></A>\n",
  1184.                     users[i].username);
  1185.  
  1186.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1187.                     return (SA_FAIL);
  1188.             }
  1189.  
  1190.             sprintf(buffer, 
  1191.                 "<A HREF=\"/sysadmin/usermgmt/upduser.stm?RCSusername=%s\" TARGET=body><IMG border=0 HEIGHT=15 WIDTH=15 SRC=\"/sysimage/system/info.gif\"> %s</A><BR>\n",
  1192.                 users[i].username, users[i].username);
  1193.  
  1194.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1195.                 return (SA_FAIL);
  1196.         }
  1197.  
  1198.     }
  1199.  
  1200.     if (sa_conn_send(saconn, "</BLOCKQUOTE>\n", SA_NULLTERM) != SA_SUCCEED)
  1201.         return (SA_FAIL);
  1202.  
  1203.     return (SA_SUCCEED);
  1204. }
  1205.  
  1206. /*
  1207. **  USER_PASSWD
  1208. **
  1209. **    Update a user' password.
  1210. **
  1211. **  Parameters:
  1212. **    sactx        Sambar Server context
  1213. **    saconn        Sambar Server connection
  1214. **    saparams    RPC Parameters
  1215. **    infop        Error parameters
  1216. **
  1217. **  Returns:
  1218. **    SA_SUCCEED | SA_FAIL
  1219. */
  1220. SA_RETCODE SA_PUBLIC
  1221. user_passwd(sactx, saconn, saparams, infop)
  1222. SA_CTX        *sactx;
  1223. SA_CONN        *saconn;
  1224. SA_PARAMS    *saparams;
  1225. SA_INT        *infop;
  1226. {
  1227.     SA_INT        datalen;
  1228.     SA_INT        passwordlen;
  1229.     SA_INT        usernamelen;
  1230.     SA_CHAR        *data;
  1231.     SA_CHAR        *password;
  1232.     SA_CHAR        *username;
  1233.     SA_PASSWD    passwd;
  1234.  
  1235.     /* What username is being updated?                                    */
  1236.     if (sa_param(sactx, saparams, "username", &username, &usernamelen) 
  1237.         != SA_SUCCEED)
  1238.     {
  1239.         *infop = SA_E_INVALIDDATA;
  1240.         sa_log2(sactx, SA_LOG_WARN,
  1241.             "user_passwd(): Expected parameter 'username'!");
  1242.         return (SA_FAIL);
  1243.     }
  1244.  
  1245.     if ((usernamelen == 0) || (usernamelen > SA_MAX_NAME))
  1246.     {
  1247.         *infop = SA_E_INVALIDDATA;
  1248.         sa_log2(sactx, SA_LOG_WARN,
  1249.             "user_update(): 'username' field left NULL!");
  1250.         return (SA_FAIL);
  1251.     }
  1252.  
  1253.     /* Lookup the username provided for update.                            */
  1254.     if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  1255.     {
  1256.         *infop = SA_E_INVALIDDATA;
  1257.         sa_log2(sactx, SA_LOG_ERROR,
  1258.             "user_passwd(): sa_passwd_lookup() failed!");
  1259.         return (SA_FAIL);
  1260.     }
  1261.  
  1262.     /* Make sure that the password is valid.                        */
  1263.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  1264.     {
  1265.         *infop = SA_E_INVALIDDATA;
  1266.         sa_log2(sactx, SA_LOG_WARN,
  1267.             "user_passwd(): Expected parameter 'password'!");
  1268.         return (SA_FAIL);
  1269.     }
  1270.     
  1271.     /* Compare with the existing password.                            */
  1272.     if (datalen != passwd.passwordlen)
  1273.     {    
  1274.         *infop = SA_E_INVALIDDATA;
  1275.         sa_log2(sactx, SA_LOG_WARN,
  1276.             "user_passwd(): Invalid password provided.");
  1277.         return (SA_FAIL);
  1278.     }
  1279.     
  1280.     if (datalen > 0)
  1281.     {
  1282.         if (memcmp(passwd.password, data, datalen) != 0)
  1283.         {
  1284.             *infop = SA_E_INVALIDDATA;
  1285.             sa_log2(sactx, SA_LOG_WARN,
  1286.                 "user_passwd(): Invalid password provided.");
  1287.             return (SA_FAIL);
  1288.         }
  1289.     }
  1290.  
  1291.     /* Get the new password.                                            */
  1292.     if (sa_param(sactx, saparams, "newpasswd", &password, &passwordlen) 
  1293.         != SA_SUCCEED)
  1294.     {
  1295.         *infop = SA_E_INVALIDDATA;
  1296.         sa_log2(sactx, SA_LOG_WARN,
  1297.             "user_passwd(): Expected parameter 'newpasswd'!");
  1298.         return (SA_FAIL);
  1299.     }
  1300.     
  1301.     /* Confirm the new password.                                        */
  1302.     if (sa_param(sactx, saparams, "confpasswd", &data, &datalen) 
  1303.         != SA_SUCCEED)
  1304.     {
  1305.         *infop = SA_E_INVALIDDATA;
  1306.         sa_log2(sactx, SA_LOG_WARN,
  1307.             "user_passwd(): Expected parameter 'confpasswd'!");
  1308.         return (SA_FAIL);
  1309.     }
  1310.  
  1311.     /* Does the new password and confirm password match?                */
  1312.     if ((passwordlen > 0) && (datalen > 0))
  1313.     {
  1314.         if ((passwordlen != datalen) ||
  1315.             (memcmp(password, data, datalen) != 0))
  1316.         {
  1317.             *infop = SA_E_INVALIDDATA;
  1318.             sa_log2(sactx, SA_LOG_WARN,
  1319.                 "user_passwd(): New & confirmation password do not match!");
  1320.             return (SA_FAIL);
  1321.         }
  1322.     }
  1323.     
  1324.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  1325.     if (passwd.passwordlen > 0)
  1326.         memcpy(passwd.password, data, passwd.passwordlen);
  1327.  
  1328.     if (sa_passwd_update(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  1329.     {
  1330.         sa_log2(sactx, SA_LOG_ERROR,
  1331.             "user_passwd(): sa_passwd_update() failed!");
  1332.         return (SA_FAIL);
  1333.     }
  1334.  
  1335.     return (SA_SUCCEED);
  1336. }
  1337.  
  1338. /*
  1339. **  USER_PROP
  1340. **
  1341. **    Lookup and return a single user property.
  1342. **
  1343. **  Parameters:
  1344. **    sactx        Sambar Server context
  1345. **    saconn        Sambar Server connection
  1346. **    saparams    RPC Parameters
  1347. **    infop        Error parameters
  1348. **
  1349. **  Return Values:
  1350. **    SA_SUCCESS | SA_FAIL
  1351. */
  1352. SA_RETCODE SA_PUBLIC
  1353. user_prop(sactx, saconn, saparams, infop)
  1354. SA_CTX        *sactx;
  1355. SA_CONN        *saconn;
  1356. SA_PARAMS    *saparams;
  1357. SA_INT        *infop;
  1358. {
  1359.     SA_PASSWD            passwd;
  1360.     SA_INT                userlen;
  1361.     SA_CHAR                *user;
  1362.     SA_INT                proplen;
  1363.     SA_CHAR                *prop;
  1364.     SA_CHAR                buffer[512];
  1365.  
  1366.     /* Get the page to direct to for user update                        */
  1367.     if (sa_param(sactx, saparams, "username", &user, &userlen) != SA_SUCCEED)
  1368.     {
  1369.         *infop = SA_E_INVALIDDATA;
  1370.         sa_log2(sactx, SA_LOG_WARN,
  1371.             "user_prop(): Expected parameter 'username'!");
  1372.         return (SA_FAIL);
  1373.     }
  1374.  
  1375.     if ((userlen == 0) || (userlen > SA_MAX_NAME))
  1376.     {
  1377.         *infop = SA_E_INVALIDDATA;
  1378.         sa_log2(sactx, SA_LOG_WARN, "user_prop(): 'username' field left NULL!");
  1379.         return (SA_FAIL);
  1380.     }
  1381.  
  1382.     /* Get the property being looked up.                                */
  1383.     if (sa_param(sactx, saparams, "prop", &prop, &proplen) != SA_SUCCEED)
  1384.     {
  1385.         *infop = SA_E_INVALIDDATA;
  1386.         sa_log2(sactx, SA_LOG_WARN, "user_prop(): Expected parameter 'prop'!");
  1387.         return (SA_FAIL);
  1388.     }
  1389.  
  1390.     if ((proplen == 0) || (proplen > SA_MAX_NAME))
  1391.     {
  1392.         *infop = SA_E_INVALIDDATA;
  1393.         sa_log2(sactx, SA_LOG_WARN, "user_prop(): 'prop' field left NULL!");
  1394.         return (SA_FAIL);
  1395.     }
  1396.  
  1397.     if (sa_passwd_lookup(sactx, user, userlen, &passwd) != SA_SUCCEED)
  1398.     {
  1399.         sprintf(buffer, "User lookup for '%s' failed.", user);
  1400.         sa_log2(sactx, SA_LOG_WARN, buffer);
  1401.         *infop = SA_E_INVALIDDATA;
  1402.         return (SA_FAIL);
  1403.     }
  1404.  
  1405.     /* Lookup and return the appropriate property                        */
  1406.     if (strcmp(prop, "group") == 0)
  1407.     {
  1408.         if (sa_conn_send(saconn, passwd.group, passwd.grouplen) != SA_SUCCEED)
  1409.             return (SA_FAIL);
  1410.     }
  1411.     else if (strcmp(prop, "password") == 0)
  1412.     {
  1413.         if (sa_conn_send(saconn, passwd.password, passwd.passwordlen) 
  1414.             != SA_SUCCEED)
  1415.         {
  1416.             return (SA_FAIL);
  1417.         }
  1418.     }
  1419.     else if (strcmp(prop, "name") == 0)
  1420.     {
  1421.         if (sa_conn_send(saconn, passwd.name, passwd.namelen) != SA_SUCCEED)
  1422.             return (SA_FAIL);
  1423.     }
  1424.     else if (strcmp(prop, "dir") == 0)
  1425.     {
  1426.         if (sa_conn_send(saconn, passwd.dir, passwd.dirlen) != SA_SUCCEED)
  1427.             return (SA_FAIL);
  1428.     }
  1429.     else if (strcmp(prop, "ftpprivs") == 0)
  1430.     {
  1431.         if (sa_param(sactx, saparams, "checked", &prop, &proplen) == SA_SUCCEED)
  1432.         {
  1433.             int        tmp;
  1434.  
  1435.             tmp = 0;
  1436.             if (proplen > 0)
  1437.                 tmp = atoi(prop);
  1438.         
  1439.             if (tmp == passwd.privs)
  1440.             {
  1441.                 if (sa_conn_send(saconn, "CHECKED", SA_NULLTERM) != SA_SUCCEED)
  1442.                     return (SA_FAIL);
  1443.             }
  1444.         }
  1445.         else
  1446.         {
  1447.             sprintf(buffer, "%ld", passwd.privs);
  1448.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1449.                 return (SA_FAIL);
  1450.         }
  1451.     }
  1452.     else if (strcmp(prop, "ftpmax") == 0)
  1453.     {
  1454.         if (passwd.ftpmax < 5)
  1455.             passwd.ftpmax = 0;
  1456.         sprintf(buffer, "%ld", passwd.ftpmax);
  1457.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1458.             return (SA_FAIL);
  1459.     }
  1460.     else if (strcmp(prop, "mbox") == 0)
  1461.     {
  1462.         if (sa_mbox_exists(sactx, user))
  1463.             strcpy(buffer, "CHECKED");
  1464.         else
  1465.             strcpy(buffer, "");
  1466.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1467.             return (SA_FAIL);
  1468.     }
  1469.     else 
  1470.     {
  1471.         sprintf(buffer, "User lookup for property '%s' failed.", prop);
  1472.         sa_log2(sactx, SA_LOG_WARN, buffer);
  1473.         *infop = SA_E_INVALIDDATA;
  1474.         return (SA_FAIL);
  1475.     }
  1476.  
  1477.     return (SA_SUCCEED);
  1478. }
  1479.  
  1480. /*
  1481. **  USER_MAILLIST
  1482. **
  1483. **    List all mail users for delete or update.
  1484. **
  1485. **  Parameters:
  1486. **    sactx        Sambar Server context
  1487. **    saconn        Sambar Server connection
  1488. **    saparams    RPC Parameters
  1489. **    infop        Error parameters
  1490. **
  1491. **  Returns:
  1492. **    SA_SUCCEED | SA_FAIL
  1493. **
  1494. **  Notes:
  1495. **    This list is truncated at 500 names.
  1496. */
  1497. SA_RETCODE SA_PUBLIC
  1498. user_maillist(sactx, saconn, saparams, infop)
  1499. SA_CTX        *sactx;
  1500. SA_CONN        *saconn;
  1501. SA_PARAMS    *saparams;
  1502. SA_INT        *infop;
  1503. {
  1504.     SA_INT            i;
  1505.     SA_INT            numusers;
  1506.     SA_USER            users[500];
  1507.     SA_CHAR            buffer[512];
  1508.     SA_MBOXINFO        info;
  1509.  
  1510.     if (sa_passwd_list(sactx, users, 500, &numusers) != SA_SUCCEED)
  1511.     {
  1512.         sa_log2(sactx, SA_LOG_ERROR,
  1513.             "user_list(): failure retrieving names list!");
  1514.         return (SA_FAIL);
  1515.     }
  1516.  
  1517.     if (sa_conn_send(saconn, "<TABLE BORDER=0 CELLPADDING=2>\n", SA_NULLTERM) 
  1518.         != SA_SUCCEED)
  1519.     {
  1520.         return (SA_FAIL);
  1521.     }
  1522.  
  1523.     if (sa_conn_send(saconn, 
  1524.         "<TR nowrap><TH>User</TH><TH>Mailbox</TH><TH>Folders</TH><TH nowrap>Read / Unread</TH><TH>Digest</TH></TR>\n",
  1525.         SA_NULLTERM) != SA_SUCCEED)
  1526.     {
  1527.         return (SA_FAIL);
  1528.     }
  1529.  
  1530.     /*
  1531.     ** Display the mail users
  1532.     */
  1533.     for (i = 0; i < numusers; i++)
  1534.     {
  1535.         sprintf(buffer, "<TR nowrap><TD><b>%s</b> </TD><TD>", 
  1536.             users[i].username);
  1537.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1538.             return (SA_FAIL);
  1539.  
  1540.         if (sa_mbox_exists(sactx, users[i].username))
  1541.         {
  1542.             sprintf(buffer, 
  1543.                 "<A HREF=\"/session/usermbox?action=delete&username=%s&RCpage=/sysadmin/mail/users.stm\"><font color=#990000>Delete</font></A></TD>",
  1544.                 users[i].username);
  1545.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1546.                 return (SA_FAIL);
  1547.  
  1548.             (void)sa_mbox_info(sactx, users[i].username, &info);
  1549.  
  1550.             sprintf(buffer, "<TD>%d</TD><TD nowrap><font size=-1>", 
  1551.                 info.folders);
  1552.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1553.                 return (SA_FAIL);
  1554.  
  1555.             if (info.readsize == 0)
  1556.                 strcpy(buffer, "0 bytes");
  1557.             else if (info.readsize < 1024)
  1558.                 strcpy(buffer, "1 KB");
  1559.             else if (info.readsize < 1024 * 1024)
  1560.                 sprintf(buffer, "%d KB", (int)(info.readsize / 1024));
  1561.             else
  1562.                 sprintf(buffer, "%d MB", (int)(info.readsize/(1024*1024)));
  1563.  
  1564.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1565.                 return (SA_FAIL);
  1566.  
  1567.             if (info.unreadsize == 0)
  1568.                 strcpy(buffer, " / 0 bytes");
  1569.             else if (info.unreadsize < 1024)
  1570.                 strcpy(buffer, " / 1 KB");
  1571.             else if (info.unreadsize < 1024 * 1024)
  1572.                 sprintf(buffer," / %d KB",(int)(info.readsize / 1024));
  1573.             else
  1574.                 sprintf(buffer," / %d MB",(int)(info.readsize/(1024*1024)));
  1575.  
  1576.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1577.                 return (SA_FAIL);
  1578.  
  1579.             if (sa_conn_send(saconn, "</font></TD><TD>", SA_NULLTERM) 
  1580.                 != SA_SUCCEED)
  1581.             {
  1582.                 return (SA_FAIL);
  1583.             }
  1584.  
  1585.             sprintf(buffer, 
  1586.                 "<A HREF=\"/sysadmin/mail/digest.stm?username=%s\"><I>Generate</I></A>",
  1587.                 users[i].username);
  1588.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1589.                 return (SA_FAIL);
  1590.  
  1591.         }
  1592.         else
  1593.         {
  1594.             sprintf(buffer, 
  1595.                 "<A HREF=\"/session/usermbox?action=create&username=%s&RCpage=/sysadmin/mail/users.stm\"><font color=#009900>Create</font></A></TD><TD>", 
  1596.                 users[i].username);
  1597.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1598.                 return (SA_FAIL);
  1599.         }
  1600.  
  1601.         if (sa_conn_send(saconn, "</TD></TR>\n", SA_NULLTERM) != SA_SUCCEED)
  1602.             return (SA_FAIL);
  1603.     }
  1604.  
  1605.     if (sa_conn_send(saconn, "</TABLE>\n", SA_NULLTERM) != SA_SUCCEED)
  1606.         return (SA_FAIL);
  1607.  
  1608.     return (SA_SUCCEED);
  1609. }
  1610.  
  1611. /*
  1612. **  USER_MBOX
  1613. **
  1614. **    Update an user mailbox
  1615. **
  1616. **  Parameters:
  1617. **    sactx        Sambar Server context
  1618. **    saconn        Sambar Server connection
  1619. **    saparams    RPC Parameters
  1620. **    infop        Error parameters
  1621. **
  1622. **  Returns:
  1623. **    SA_SUCCEED | SA_FAIL
  1624. */
  1625. SA_RETCODE SA_PUBLIC
  1626. user_mailbox(sactx, saconn, saparams, infop)
  1627. SA_CTX        *sactx;
  1628. SA_CONN        *saconn;
  1629. SA_PARAMS    *saparams;
  1630. SA_INT        *infop;
  1631. {
  1632.     SA_BOOL        create;
  1633.     SA_INT        datalen;
  1634.     SA_CHAR        *data;
  1635.     SA_PASSWD    passwd;
  1636.  
  1637.     if (sa_param(sactx, saparams, "action", &data, &datalen) != SA_SUCCEED)
  1638.     {
  1639.         *infop = SA_E_INVALIDDATA;
  1640.         sa_log2(sactx, SA_LOG_WARN,
  1641.             "user_mailbox(): Expected parameter 'action'!");
  1642.         return (SA_FAIL);
  1643.     }
  1644.  
  1645.     if (stricmp(data, "create") == 0)
  1646.     {
  1647.         create = 1;
  1648.     }
  1649.     else if (stricmp(data, "delete") == 0)
  1650.     {
  1651.         create = 0;
  1652.     }
  1653.     else
  1654.     {
  1655.         *infop = SA_E_INVALIDDATA;
  1656.         sa_log2(sactx, SA_LOG_WARN,
  1657.             "user_mailbox(): Parameter 'action' not create/delete!");
  1658.         return (SA_FAIL);
  1659.     }
  1660.     
  1661.     if ((sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  1662.         || (datalen == 0) || (datalen > SA_MAX_NAME))
  1663.     {
  1664.         *infop = SA_E_INVALIDDATA;
  1665.         sa_log2(sactx, SA_LOG_WARN,
  1666.             "user_mailbox(): Expected parameter 'username'!");
  1667.         return (SA_FAIL);
  1668.     }
  1669.  
  1670.     /* Verify the user account exists.                                    */
  1671.     if (sa_passwd_lookup(sactx, data, datalen, &passwd) == SA_SUCCEED)
  1672.     {
  1673.         /* Create the user mailbox.                                        */
  1674.         if (create)
  1675.         {
  1676.             if (sa_mbox_create(sactx, data) != SA_SUCCEED)
  1677.             {
  1678.                 sa_log2(sactx, SA_LOG_ERROR, 
  1679.                     "user_mailbox(): sa_mbox_create() failed!");
  1680.             }
  1681.         }
  1682.         else
  1683.         {
  1684.             if (sa_mbox_delete(sactx, data) != SA_SUCCEED)
  1685.             {
  1686.                 sa_log2(sactx, SA_LOG_ERROR, 
  1687.                     "user_mailbox(): sa_mbox_delete() failed!");
  1688.             }
  1689.         }
  1690.     }
  1691.  
  1692.     return (SA_SUCCEED);
  1693. }
  1694.  
  1695.  
  1696. /*
  1697. **  FTP_CONNECT
  1698. **
  1699. **    Process an FTP Connect request. Verify the username/password against 
  1700. **    the Sambar Server password interfaces and return the root directory
  1701. **    and priviledges.
  1702. **
  1703. **  Parameters:
  1704. **    sactx            Sambar Server Application context to release.
  1705. **    saconn            Sambar Server User Connection handle.
  1706. **    username        Name of the user logging in.
  1707. **    usernamelen        Length of the user name
  1708. **    password        Password of the user logging in.
  1709. **    passwordlen        Length of the password.
  1710. **    ftpresp            FTP response structure.
  1711. **
  1712. **  Return Values:
  1713. **    SA_SUCCESS         Login Accepted.
  1714. **    SA_FAIL            Login Denied.
  1715. */
  1716. SA_RETCODE SA_PUBLIC
  1717. ftp_connect(sactx, name, namelen, password, passwordlen, ftpresp)
  1718. SA_CTX        *sactx;
  1719. SA_CHAR        *name;
  1720. SA_INT        namelen;
  1721. SA_CHAR        *password;
  1722. SA_INT        passwordlen;
  1723. SA_FTP        *ftpresp;
  1724. {
  1725.     SA_BOOL            ntauth;
  1726.     SA_BOOL            sqlauth;
  1727.     SA_BOOL            radiusauth;
  1728.     SA_BOOL            usepasswd;
  1729.     SA_BOOL            status;
  1730.     SA_PASSWD        passwd;
  1731.     SA_CHAR            buffer[512];
  1732.  
  1733.     ntauth = 0;
  1734.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_NTAUTH, buffer, 30, 
  1735.         (SA_INT *)NULL) == SA_SUCCEED)
  1736.     {
  1737.         if (stricmp(buffer, "true") == 0)
  1738.             ntauth = 1;
  1739.     }
  1740.  
  1741.     radiusauth = 0;
  1742.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_RADIUSAUTH, buffer, 30, 
  1743.         (SA_INT *)NULL) == SA_SUCCEED)
  1744.     {
  1745.         if (stricmp(buffer, "true") == 0)
  1746.             radiusauth = 1;
  1747.     }
  1748.  
  1749.     sqlauth = 0;
  1750.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SQLAUTH, buffer, 30, 
  1751.         (SA_INT *)NULL) == SA_SUCCEED)
  1752.     {
  1753.         if (stricmp(buffer, "true") == 0)
  1754.             sqlauth = 1;
  1755.     }
  1756.  
  1757.     usepasswd = 0;
  1758.     if ((ntauth) || (radiusauth))
  1759.     {
  1760.         if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen,
  1761.             &status) != SA_SUCCEED) || (!status))
  1762.         {
  1763.             sprintf(buffer, 
  1764.                 "%sFTP login for user '%s' failed - bad password (%s)", 
  1765.                 (radiusauth ? "Radius " : (ntauth ? "NT " : "")),
  1766.                 name, password);
  1767.             sa_log2(sactx, SA_LOG_WARN, buffer);
  1768.             return (SA_FAIL);
  1769.         }
  1770.  
  1771.         ftpresp->privs = SA_PRIV_READONLY;
  1772.         ftpresp->ftpmax = 0;
  1773.  
  1774.         if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_DOCSDIR, ftpresp->dir, 
  1775.             SA_MAX_NAME, &ftpresp->dirlen) != SA_SUCCEED)
  1776.         {
  1777. #ifdef    WIN32
  1778.             strcpy(ftpresp->dir, "c:/temp");
  1779. #else
  1780.             strcpy(ftpresp->dir, "/tmp");
  1781. #endif
  1782.             ftpresp->dirlen = strlen(ftpresp->dir);
  1783.         }
  1784.  
  1785.         if (sa_passwd_lookup(sactx, name, namelen, &passwd) == SA_SUCCEED)
  1786.             usepasswd = 1;
  1787.     }
  1788.     else if (sqlauth)
  1789.     {
  1790.         usepasswd = 1;
  1791.         if (sa_passwd_sqlauth(sactx, (SA_CONN *)NULL, name, namelen, password, 
  1792.             passwordlen, &passwd) != SA_SUCCEED)
  1793.         {
  1794.             sprintf(buffer, "SQL FTP login for user '%s' failed.", name);
  1795.             sa_log2(sactx, SA_LOG_WARN, buffer);
  1796.             return (SA_FAIL);
  1797.         }
  1798.     }
  1799.     else
  1800.     {
  1801.         usepasswd = 1;
  1802.         if (sa_passwd_lookup(sactx, name, namelen, &passwd) != SA_SUCCEED)
  1803.         {
  1804.             sprintf(buffer, "FTP login for user '%s' failed.", name);
  1805.             sa_log2(sactx, SA_LOG_WARN, buffer);
  1806.             return (SA_FAIL);
  1807.         }
  1808.  
  1809.         /* Verify the passwords are the same                            */
  1810.         if ((passwd.passwordlen != passwordlen) ||
  1811.             (strncmp(passwd.password, password, passwordlen) != 0))
  1812.         {
  1813.             /* Special case for anonymous user - NULL password match OK    */
  1814.             if ((namelen != 9) || (strncmp(name, "anonymous", 9) != 0))
  1815.             {
  1816.                 sprintf(buffer, 
  1817.                     "FTP login for user '%s' failed - bad password (%s)", 
  1818.                     name, password);
  1819.                 sa_log2(sactx, SA_LOG_WARN, buffer);
  1820.                 return (SA_FAIL);
  1821.             }
  1822.         }
  1823.     }
  1824.  
  1825.     if (usepasswd)
  1826.     {
  1827.         /* Return the directory and access priviledges                    */
  1828.         ftpresp->privs = passwd.privs;
  1829.         ftpresp->ftpmax = passwd.ftpmax;
  1830.  
  1831.         ftpresp->dirlen = passwd.dirlen;
  1832.         if (ftpresp->dirlen > 0)
  1833.             strncpy(ftpresp->dir, passwd.dir, ftpresp->dirlen);
  1834.         ftpresp->dir[ftpresp->dirlen] = '\0';
  1835.  
  1836.         ftpresp->grouplen = passwd.grouplen;
  1837.         if (ftpresp->grouplen > 0)
  1838.             strncpy(ftpresp->group, passwd.group, ftpresp->grouplen);
  1839.         ftpresp->group[ftpresp->grouplen] = '\0';
  1840.     }
  1841.  
  1842. #ifdef DEBUG
  1843.     sprintf(buffer, "%sFTP User '%s' logged in.", 
  1844.         (radiusauth ? "Radius " : (sqlauth ? "SQL " : (ntauth ? "NT " : ""))), 
  1845.         name);
  1846.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  1847. #endif    /* DEBUG */
  1848.  
  1849.     return (SA_SUCCEED);
  1850. }
  1851.  
  1852. /*
  1853. **  MAIL_CONNECT
  1854. **
  1855. **    Process an MAIL Connect request. Verify the username/password against 
  1856. **    the Sambar Server password interfaces.
  1857. **
  1858. **  Parameters:
  1859. **    sactx            Sambar Server Application context to release.
  1860. **    saconn            Sambar Server User Connection handle.
  1861. **    username        Name of the user logging in.
  1862. **    usernamelen        Length of the user name
  1863. **    password        Password of the user logging in.
  1864. **    passwordlen        Length of the password.
  1865. **
  1866. **  Return Values:
  1867. **    SA_SUCCESS         Login Accepted.
  1868. **    SA_FAIL            Login Denied.
  1869. */
  1870. SA_RETCODE SA_PUBLIC
  1871. mail_connect(sactx, name, namelen, password, passwordlen)
  1872. SA_CTX        *sactx;
  1873. SA_CHAR        *name;
  1874. SA_INT        namelen;
  1875. SA_CHAR        *password;
  1876. SA_INT        passwordlen;
  1877. {
  1878.     SA_BOOL        status;
  1879.     SA_CHAR        buffer[512];
  1880.  
  1881.     if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen, &status) 
  1882.         != SA_SUCCEED) || (!status))
  1883.     {
  1884.         sprintf(buffer, 
  1885.             "MAIL login for user '%s' failed - bad password (%s).", 
  1886.             name, password);
  1887.         sa_log2(sactx, SA_LOG_WARN, buffer);
  1888.         return (SA_FAIL);
  1889.     }
  1890.  
  1891. #ifdef DEBUG
  1892.     sprintf(buffer, "MAIL User '%s' logged in.", name);
  1893.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  1894. #endif    /* DEBUG */
  1895.  
  1896.     return (SA_SUCCEED);
  1897. }
  1898.  
  1899. /*
  1900. **  TELNET_CONNECT
  1901. **
  1902. **    Process an Telnet Connect request. Verify the username/password against 
  1903. **    the Sambar Server password interfaces.
  1904. **
  1905. **  Parameters:
  1906. **    sactx            Sambar Server Application context to release.
  1907. **    saconn            Sambar Server User Connection handle.
  1908. **    username        Name of the user logging in.
  1909. **    usernamelen        Length of the user name
  1910. **    password        Password of the user logging in.
  1911. **    passwordlen        Length of the password.
  1912. **
  1913. **  Return Values:
  1914. **    SA_SUCCESS         Login Accepted.
  1915. **    SA_FAIL            Login Denied.
  1916. */
  1917. SA_RETCODE SA_PUBLIC
  1918. telnet_connect(sactx, name, namelen, password, passwordlen)
  1919. SA_CTX        *sactx;
  1920. SA_CHAR        *name;
  1921. SA_INT        namelen;
  1922. SA_CHAR        *password;
  1923. SA_INT        passwordlen;
  1924. {
  1925.     SA_BOOL        status;
  1926.     SA_CHAR        buffer[512];
  1927.  
  1928.     if ((sa_passwd_verify(sactx, name, namelen, password, passwordlen, &status) 
  1929.         != SA_SUCCEED) || (!status))
  1930.     {
  1931.         sprintf(buffer, 
  1932.             "Telnet login for user '%s' failed - bad password (%s).", 
  1933.             name, password);
  1934.         sa_log2(sactx, SA_LOG_WARN, buffer);
  1935.         return (SA_FAIL);
  1936.     }
  1937.  
  1938. #ifdef DEBUG
  1939.     sprintf(buffer, "Telnet User '%s' logged in.", name);
  1940.     sa_log2(sactx, SA_LOG_TRACE, buffer);
  1941. #endif    /* DEBUG */
  1942.  
  1943.     return (SA_SUCCEED);
  1944. }
  1945.  
  1946. /*
  1947. **  GROUP_ADD
  1948. **
  1949. **    Add a new group
  1950. **
  1951. **  Parameters:
  1952. **    sactx        Sambar Server context
  1953. **    saconn        Sambar Server connection
  1954. **    saparams    RPC Parameters
  1955. **    infop        Error parameters
  1956. **
  1957. **  Returns:
  1958. **    SA_SUCCEED | SA_FAIL
  1959. */
  1960. SA_RETCODE SA_PUBLIC
  1961. group_add(sactx, saconn, saparams, infop)
  1962. SA_CTX        *sactx;
  1963. SA_CONN        *saconn;
  1964. SA_PARAMS    *saparams;
  1965. SA_INT        *infop;
  1966. {
  1967.     SA_CHAR        *data;
  1968.     SA_INT        datalen;
  1969.  
  1970.     if (sa_param(sactx, saparams, "groupname", &data, &datalen) != SA_SUCCEED)
  1971.     {
  1972.         *infop = SA_E_INVALIDDATA;
  1973.         sa_log2(sactx, SA_LOG_WARN, 
  1974.             "group_add(): Expected parameter 'groupname'!");
  1975.         return (SA_FAIL);
  1976.     }
  1977.     
  1978.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  1979.     {
  1980.         *infop = SA_E_INVALIDDATA;
  1981.         sa_log2(sactx, SA_LOG_WARN,
  1982.             "group_add(): 'name' field left NULL!");
  1983.         return (SA_FAIL);
  1984.     }
  1985.  
  1986.     /* Can't create the group "other"                                    */
  1987.     if ((datalen == 5) && 
  1988.         (memcmp(data, SA_DEFAULT_GROUP, strlen(SA_DEFAULT_GROUP)) == 0))
  1989.     {
  1990.         *infop = SA_E_INVALIDDATA;
  1991.         sa_log2(sactx, SA_LOG_WARN,
  1992.             "group_add(): 'other' group already exists!");
  1993.         return (SA_FAIL);
  1994.     }
  1995.  
  1996.     if (sa_group_add(sactx, data, datalen) != SA_SUCCEED)
  1997.     {
  1998.         *infop = SA_E_ALREADYDEFINED;
  1999.         sa_log2(sactx, SA_LOG_ERROR,
  2000.             "group_add(): sa_group_add() failed (already defined?)");
  2001.         return (SA_FAIL);
  2002.     }
  2003.  
  2004.     return (SA_SUCCEED);
  2005. }
  2006.  
  2007. /*
  2008. **  GROUP_DELETE
  2009. **
  2010. **    Delete an existing group
  2011. **
  2012. **  Parameters:
  2013. **    sactx        Sambar Server context
  2014. **    saconn        Sambar Server connection
  2015. **    saparams    RPC Parameters
  2016. **    infop        Error parameters
  2017. **
  2018. **  Returns:
  2019. **    SA_SUCCEED | SA_FAIL
  2020. **
  2021. **    Notes:
  2022. **    No users can belong to the group.
  2023. */
  2024. SA_RETCODE SA_PUBLIC
  2025. group_delete(sactx, saconn, saparams, infop)
  2026. SA_CTX        *sactx;
  2027. SA_CONN        *saconn;
  2028. SA_PARAMS    *saparams;
  2029. SA_INT        *infop;
  2030. {
  2031.     SA_INT        datalen;
  2032.     SA_CHAR        *data;
  2033.  
  2034.     if (sa_param(sactx, saparams, "groupname", &data, &datalen) != SA_SUCCEED)
  2035.     {
  2036.         *infop = SA_E_INVALIDDATA;
  2037.         sa_log2(sactx, SA_LOG_WARN,
  2038.             "group_delete(): Expected parameter 'groupname'!");
  2039.         return (SA_FAIL);
  2040.     }
  2041.  
  2042.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  2043.     {
  2044.         *infop = SA_E_INVALIDDATA;
  2045.         sa_log2(sactx, SA_LOG_WARN,
  2046.             "group_delete(): 'groupname' field left NULL!");
  2047.         return (SA_FAIL);
  2048.     }
  2049.  
  2050.     /* Can't delete the group "other"                                    */
  2051.     if ((datalen == 5) && 
  2052.         (memcmp(data, SA_DEFAULT_GROUP, strlen(SA_DEFAULT_GROUP)) == 0))
  2053.     {
  2054.         *infop = SA_E_INVALIDDATA;
  2055.         sa_log2(sactx, SA_LOG_WARN,
  2056.             "group_delete(): 'other' group cannot be deleted!");
  2057.         return (SA_FAIL);
  2058.     }
  2059.  
  2060.     /* Should only be allowed to do this if the group has no users.        */
  2061.     (SA_VOID)sa_group_delete(sactx, data, datalen);
  2062.  
  2063.     return (SA_SUCCEED);
  2064. }
  2065.  
  2066. /*
  2067. **  GROUP_SELECT
  2068. **
  2069. **    List all groups for selection.
  2070. **
  2071. **  Parameters:
  2072. **    sactx        Sambar Server context
  2073. **    saconn        Sambar Server connection
  2074. **    saparams    RPC Parameters
  2075. **    infop        Error parameters
  2076. **
  2077. **  Returns:
  2078. **    SA_SUCCEED | SA_FAIL
  2079. **
  2080. **  Notes:
  2081. **    This list is truncated at 100 names.
  2082. **    The group other always exists and is used for users with unrecognized
  2083. **    group names.
  2084. */
  2085. SA_RETCODE SA_PUBLIC
  2086. group_select(sactx, saconn, saparams, infop)
  2087. SA_CTX        *sactx;
  2088. SA_CONN        *saconn;
  2089. SA_PARAMS    *saparams;
  2090. SA_INT        *infop;
  2091. {
  2092.     SA_INT            i;
  2093.     SA_BOOL            found;
  2094.     SA_BOOL            selected;
  2095.     SA_INT            grouplen;
  2096.     SA_INT            userlen;
  2097.     SA_INT            numgroups;
  2098.     SA_CHAR            *user;
  2099.     SA_PASSWD        passwd;
  2100.     SA_CHAR            group[SA_MAX_NAME + 1];
  2101.     SA_GROUP        groups[100];
  2102.     SA_CHAR            buffer[512];
  2103.  
  2104.     /* If a name is provided make it SELECTED in the OPTION list        */
  2105.     userlen = 0;
  2106.     grouplen = 0;
  2107.     (SA_VOID)sa_param(sactx, saparams, "username", &user, &userlen);
  2108.  
  2109.     if ((userlen > 0) && (userlen < SA_MAX_NAME))
  2110.     {
  2111.         if (sa_passwd_lookup(sactx, user, userlen, &passwd) != SA_SUCCEED)
  2112.         {
  2113.             sprintf(buffer, "User lookup for '%s' failed.", user);
  2114.             sa_log2(sactx, SA_LOG_WARN, buffer);
  2115.             *infop = SA_E_INVALIDDATA;
  2116.             return (SA_FAIL);
  2117.         }
  2118.  
  2119.         grouplen = passwd.grouplen;
  2120.         if (grouplen > 0)
  2121.             memcpy(group, passwd.group, grouplen);
  2122.     }
  2123.  
  2124.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  2125.     {
  2126.         sa_log2(sactx, SA_LOG_ERROR,
  2127.             "group_select(): failure retrieving groups list!");
  2128.         return (SA_FAIL);
  2129.     }
  2130.  
  2131.     /* We could sort the names alphabetically at this point...            */
  2132.  
  2133.     /* Display the list of groups.                                        */
  2134.     found = 0;
  2135.     for (i = 0; i < numgroups; i++)
  2136.     {
  2137.         selected = 0;
  2138.         if ((grouplen > 0) &&
  2139.             (groups[i].namelen == grouplen) &&
  2140.             (memcmp(group, groups[i].name, grouplen) == 0))
  2141.         {
  2142.             selected = 1;
  2143.             found = 1;
  2144.         }
  2145.  
  2146.         sprintf(buffer, "<OPTION %s>%s\n", (selected ? "SELECTED" : ""),
  2147.             groups[i].name);
  2148.  
  2149.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  2150.             return (SA_FAIL);
  2151.     }
  2152.  
  2153.     /* The group "other" always exists.                                    */
  2154.     sprintf(buffer, "<OPTION %s>%s\n", (found ? "" : "SELECTED"),
  2155.         SA_DEFAULT_GROUP);
  2156.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  2157.         return (SA_FAIL);
  2158.  
  2159.     return (SA_SUCCEED);
  2160. }
  2161.  
  2162. /*
  2163. **  GROUP_LIST
  2164. **
  2165. **    List all groups for delete.
  2166. **
  2167. **  Parameters:
  2168. **    sactx        Sambar Server context
  2169. **    saconn        Sambar Server connection
  2170. **    saparams    RPC Parameters
  2171. **    infop        Error parameters
  2172. **
  2173. **  Returns:
  2174. **    SA_SUCCEED | SA_FAIL
  2175. **
  2176. **  Notes:
  2177. **    This list is truncated at 100 names.
  2178. **    The group "other" always exists and is the default group.
  2179. */
  2180. SA_RETCODE SA_PUBLIC
  2181. group_list(sactx, saconn, saparams, infop)
  2182. SA_CTX        *sactx;
  2183. SA_CONN        *saconn;
  2184. SA_PARAMS    *saparams;
  2185. SA_INT        *infop;
  2186. {
  2187.     SA_INT            i;
  2188.     SA_INT            numgroups;
  2189.     SA_GROUP        groups[100];
  2190.     SA_CHAR            buffer[512];
  2191.  
  2192.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  2193.     {
  2194.         sa_log2(sactx, SA_LOG_ERROR,
  2195.             "group_list(): failure retrieving groups list!");
  2196.         return (SA_FAIL);
  2197.     }
  2198.  
  2199.     /* We could sort the list alphabetically at this point.                */
  2200.  
  2201.     /* Display the list of groups.                                        */
  2202.     for (i = 0; i < numgroups; i++)
  2203.     {
  2204.         sprintf(buffer, 
  2205.             "<A TARGET=_top HREF=\"/session/delgroup?groupname=%s&RCpage=/sysadmin/usermgmt/users.htm\" onClick=\"return confirmDelete()\"><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/trash.gif\"></A> %s<BR>\n",
  2206.             groups[i].name, groups[i].name);
  2207.  
  2208.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  2209.             return (SA_FAIL);
  2210.     }
  2211.  
  2212.     return (SA_SUCCEED);
  2213. }
  2214.  
  2215. /*
  2216. **  USER__INLIST
  2217. **
  2218. **    Determine if the string is in the space separated list of values.
  2219. **
  2220. **  Parameters:
  2221. **    list        The space-spearated list to examine.
  2222. **    listlen        The length of the list.
  2223. **    value        The value to examine.
  2224. **    valuelen    The length of the value string.
  2225. **
  2226. **  Returns:
  2227. **    SA_TRUE | SA_FALSE
  2228. */
  2229. static SA_BOOL 
  2230. user__inlist(list, listlen, value, valuelen)
  2231. SA_CHAR        *list;
  2232. SA_INT        listlen;
  2233. SA_CHAR        *value;
  2234. SA_INT        valuelen;
  2235. {
  2236.     SA_INT        pos;
  2237.     SA_INT        head;
  2238.  
  2239.     if (listlen == SA_NULLTERM)
  2240.         listlen = strlen(list);
  2241.  
  2242.     if (valuelen == SA_NULLTERM)
  2243.         valuelen = strlen(value);
  2244.  
  2245.     if ((listlen == 0) || (valuelen == 0))
  2246.         return (0);
  2247.  
  2248.     /*
  2249.     ** See if the value is in the list.
  2250.     */
  2251.     pos = 0;
  2252.     while (pos < listlen)
  2253.     {
  2254.         if ((list[pos] != ' ') && (list[pos] != ','))
  2255.         {
  2256.             head = pos;
  2257.             while ((pos < listlen) && (list[pos] != ' ') && (list[pos] != ','))
  2258.                 pos++;
  2259.     
  2260.             if (pos - head != valuelen)
  2261.             {
  2262.                 pos++;
  2263.                 continue;
  2264.             }
  2265.  
  2266.             /*
  2267.             ** Determine if the index suffix matches
  2268.             */
  2269.             if (memcmp(&list[head], value, valuelen) == 0)
  2270.                 return (1);
  2271.         }
  2272.     
  2273.         pos++;
  2274.     }
  2275.  
  2276.     return (0);
  2277. }
  2278.