home *** CD-ROM | disk | FTP | other *** search
/ Chip 1999 September / CHIPCD_9_99.iso / software / serwery_www / sambar / _setup.1 / login.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-25  |  36.0 KB  |  1,439 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. **        group_add
  24. **        group_delete
  25. **        group_list
  26. **        group_select
  27. **        ftp_connect
  28. **
  29. **
  30. ** History:
  31. ** Chg#    Date    Description                                                Resp
  32. ** ----    -------    -------------------------------------------------------    ----
  33. **         27JAN96    Created                                                    sambar
  34. **         29MAR97    Added user list and update functions                    sambar
  35. **         30MAR97    Added FTP connection security                            sambar
  36. **         10OCT97    Added user password interface                            sambar
  37. **        14NOV97 Added group management                                    sambar
  38. */
  39.  
  40. #include    <stdio.h>
  41. #include    <stdlib.h>
  42. #include    <memory.h>
  43. #include    <string.h>
  44. #include    <login.h>
  45.  
  46. /*
  47. ** Login RPC Commands
  48. */
  49. typedef struct login__rpcs
  50. {
  51.     SA_CHAR        *name;
  52.     SA_RPCPARAM    *params;
  53.     SA_INT        numparams;
  54.     SA_INT        auth;
  55.     SA_VOID        *func;
  56.     SA_CHAR        *descr;
  57. } LOGIN__RPCS;
  58.  
  59. static SA_RPCPARAM    adduserp [] =
  60. {
  61.     { "username",     1,    "User login." },
  62.     { "password",     0,    "User password." },
  63.     { "group",         0,    "User group." },
  64.     { "name",         0,    "User name." },
  65.     { "dir",         0,    "Ftp directory of the user." },
  66.     { "ftpprivs",     1,    "FTP priviledges of the user." },
  67.     { "nntpprivs",     1,    "NNTP priviledges of the user." }
  68. };
  69. static SA_RPCPARAM    upduserp [] =
  70. {
  71.     { "username",     1,    "User login." },
  72.     { "password",     0,    "User password." },
  73.     { "group",         0,    "User group." },
  74.     { "name",         0,    "User name." },
  75.     { "dir",         0,    "Ftp directory of the user." },
  76.     { "ftpprivs",     1,    "FTP priviledges of the user." },
  77.     { "nntpprivs",     1,    "NNTP priviledges of the user." }
  78. };
  79. static SA_RPCPARAM    deluserp [] =
  80. {
  81.     { "username",     1,    "User login." }
  82. };
  83. static SA_RPCPARAM    userpropp [] =
  84. {
  85.     { "username",     1,    "User login." },
  86.     { "prop",     1,    "User property: group,password,name,dir,ftpprivs,nntpprivs." }
  87. };
  88. static SA_RPCPARAM    selectuserp [] =
  89. {
  90.     { "username",     0,    "User login." },
  91. };
  92. static SA_RPCPARAM    addgroupp [] =
  93. {
  94.     { "groupname",     1,    "Symbolic name of the group." }
  95. };
  96. static SA_RPCPARAM    delgroupp [] =
  97. {
  98.     { "groupname",     1,    "Symbolic name of the group." }
  99. };
  100. static SA_RPCPARAM    selectgroupp [] =
  101. {
  102.     { "username",     0,    "User to test against group list." }
  103. };
  104. static SA_RPCPARAM    userpasswdp [] =
  105. {
  106.     { "username",     1,    "User login." },
  107.     { "password",     0,    "Existing password for the user." },
  108.     { "newpasswd",     0,    "New password for the user." }
  109. };
  110.  
  111. static LOGIN__RPCS        login_rpcs [] =
  112. {
  113.     { "adduser",     adduserp,    sizeof(adduserp)/sizeof(SA_RPCPARAM),
  114.        SA_AUTHORIZATION_ADMIN,    (SA_VOID *)user_add,
  115.       "Add a user to the system." },
  116.     { "upduser",     upduserp,    sizeof(upduserp)/sizeof(SA_RPCPARAM),    
  117.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_update,
  118.       "Update a user." }, 
  119.     { "deluser",    deluserp,    sizeof(deluserp)/sizeof(SA_RPCPARAM),     
  120.        SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_delete,
  121.       "Delete a user from the system." },
  122.     { "userprop",    userpropp,    sizeof(userpropp)/sizeof(SA_RPCPARAM),     
  123.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_prop,
  124.       "Get a single user attribute for display." },
  125.     { "listusers",    NULL, 0,
  126.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_list,
  127.       "List users for update/delete." },
  128.     { "selectuser",    selectuserp,    sizeof(selectuserp)/sizeof(SA_RPCPARAM),    
  129.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)user_select,
  130.       "List users for selection in a pick list." },
  131.  
  132.     { "addgroup",    addgroupp,    sizeof(addgroupp)/sizeof(SA_RPCPARAM),     
  133.       SA_AUTHORIZATION_ADMIN,    (SA_VOID *)group_add,
  134.       "Add a group to the system." },
  135.     { "delgroup",     delgroupp,    sizeof(delgroupp)/sizeof(SA_RPCPARAM),    
  136.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_delete,
  137.       "Delete a group from the system." },
  138.     { "listgroups",    NULL, 0,
  139.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_list,
  140.       "List groups for delete." },
  141.     { "selectgroup",selectgroupp,    sizeof(selectgroupp)/sizeof(SA_RPCPARAM),
  142.       SA_AUTHORIZATION_ADMIN,     (SA_VOID *)group_select,
  143.       "List groups for selection in a pick list." },
  144.  
  145.     { "userpasswd",    userpasswdp,    sizeof(userpasswdp)/sizeof(SA_RPCPARAM),    
  146.       SA_AUTHORIZATION_ALL,        (SA_VOID *)user_passwd,
  147.       "Interface to allow users to change their password." }
  148. };
  149.  
  150. /*
  151. **  LOGIN_INIT
  152. **
  153. **    Initialize the Login/Logout/Profile Interfaces for use by the 
  154. **    Sambar Server plugins.
  155. **
  156. **
  157. **  Parameters:
  158. **    sactx        Sambar Server context
  159. **
  160. **  Returns:
  161. **    SA_SUCCEED | SA_FAIL
  162. */
  163. SA_RETCODE SA_PUBLIC
  164. login_init(sactx)
  165. SA_CTX        *sactx;
  166. {
  167.     int        i;
  168.  
  169.     /* Register the User RPCs with the server                            */
  170.     for (i = 0; i < sizeof(login_rpcs) / sizeof(LOGIN__RPCS); i++)
  171.     {
  172.         if (sa_cmd_init(sactx, login_rpcs[i].name, login_rpcs[i].params, 
  173.             login_rpcs[i].numparams, login_rpcs[i].auth, login_rpcs[i].descr,
  174.             (SA_RPCFUNC)login_rpcs[i].func) != SA_SUCCEED)
  175.         {
  176.             sa_log(sactx, "Unable to initialize User Management RPCs");
  177.             return (SA_FAIL);
  178.         } 
  179.     }
  180.  
  181.     sa_log(sactx, "Login/Logout/Profile Management Initialized");
  182.  
  183.     return (SA_SUCCEED);
  184. }
  185.  
  186. /*
  187. **  USER_LOGIN
  188. **
  189. **    Login a user.  Verify the username/password against the Sambar Server
  190. **    password interfaces.  Store some profile information for use.
  191. **
  192. **  Parameters:
  193. **    sactx            Sambar Server Application context to release.
  194. **    saconn            Sambar Server User Connection handle.
  195. **    username        Name of the user logging in.
  196. **    usernamelen        Length of the user name
  197. **    password        Password of the user logging in.
  198. **    passwordlen        Length of the password.
  199. **    infop            Error return code
  200. **
  201. **  Return Values:
  202. **    SA_SUCCESS | SA_FAIL
  203. */
  204. SA_RETCODE SA_PUBLIC
  205. user_login(sactx, saconn, username, usernamelen, password, passwordlen, infop)
  206. SA_CTX        *sactx;
  207. SA_CONN        *saconn;
  208. SA_CHAR        *username;
  209. SA_INT        usernamelen;
  210. SA_CHAR        *password;
  211. SA_INT        passwordlen;
  212. SA_INT        *infop;
  213. {
  214.     SA_PASSWD            passwd;
  215.     LOGIN_PROFILE        *profile;
  216.     SA_CHAR                buffer[512];
  217.  
  218.     if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  219.     {
  220.         sprintf(buffer, "Login for user '%s' failed.", username);
  221.         sa_log(sactx, buffer);
  222.         *infop = SA_E_INVALIDLOGIN;
  223.         return (SA_FAIL);
  224.     }
  225.  
  226.     /* Verify the passwords are the same                                */
  227.     if ((passwd.passwordlen != passwordlen) ||
  228.         (strncmp(passwd.password, password, passwordlen) != 0))
  229.     {
  230.         sprintf(buffer, "Login for user '%s' failed - bad password (%s)", 
  231.             username, password);
  232.         sa_log(sactx, buffer);
  233.         *infop = SA_E_INVALIDLOGIN;
  234.         return (SA_FAIL);
  235.     }
  236.  
  237.     /* Allocate and populate a user profile structure                    */
  238.     profile = (LOGIN_PROFILE *)malloc(sizeof(LOGIN_PROFILE));
  239.     if (profile == (LOGIN_PROFILE *)NULL)
  240.     {
  241.         sprintf(buffer, "Login for user '%s' failed - no memory", username);
  242.         sa_log(sactx, buffer);
  243.         *infop = SA_E_INVALIDLOGIN;
  244.         return (SA_FAIL);
  245.     }
  246.  
  247.     if (passwd.namelen > 0)
  248.         memcpy(profile->name, passwd.name, passwd.namelen);
  249.     if (passwd.grouplen > 0)
  250.         memcpy(profile->group, passwd.group, passwd.grouplen);
  251.  
  252.     memcpy(profile->username, username, usernamelen);
  253.  
  254.     profile->name[passwd.namelen] = '\0';
  255.     profile->group[passwd.grouplen] = '\0';
  256.     profile->username[usernamelen] = '\0';
  257.  
  258.     /* Save the user's profile handle with the user connection            */
  259.     if (sa_conn_key(saconn, SA_SET, LOGIN_PROFILE_KEY, (SA_VOID **)profile)
  260.         != SA_SUCCEED)
  261.     {
  262.         (SA_VOID)free(profile);
  263.         sa_log(sactx, "sa_conn_key(SET, LOGIN_PROFILE_KEY) failed!");
  264.         return (SA_FAIL);
  265.     }
  266.  
  267. #ifdef DEBUG
  268.     sprintf(buffer, "User '%s' logged in.", username);
  269.     sa_log(sactx, buffer);
  270. #endif    /* DEBUG */
  271.  
  272.     return (SA_SUCCEED);
  273. }
  274.  
  275. /*
  276. **  USER_LOGOUT
  277. **
  278. **    Log out a user.  Free profile resources.
  279. **
  280. **  Parameters:
  281. **    sactx        Sambar Server Application context to release.
  282. **    saconn        Sambar Server User Connection handle.
  283. **
  284. **  Return Values:
  285. **    SA_SUCCESS | SA_FAIL
  286. */
  287. SA_RETCODE SA_PUBLIC
  288. user_logout(sactx, saconn)
  289. SA_CTX        *sactx;
  290. SA_CONN        *saconn;
  291. {
  292.     LOGIN_PROFILE    *profile;
  293. #ifdef DEBUG
  294.     SA_CHAR            buffer[512];
  295. #endif    /* DEBUG */
  296.  
  297.     /* Get the user's pillar handle from the user context                */
  298.     if (sa_conn_key(saconn, SA_GET, LOGIN_PROFILE_KEY, (SA_VOID **)&profile)
  299.         != SA_SUCCEED)
  300.     {
  301.         /* User never completed login                                    */
  302.         return (SA_SUCCEED);
  303.     }
  304.  
  305. #ifdef DEBUG
  306.     sprintf(buffer, "User '%s' logged out.", profile->username);
  307.     sa_log(sactx, buffer);
  308. #endif    /* DEBUG */
  309.  
  310.     (void)free(profile);
  311.  
  312.     return (SA_SUCCEED);
  313. }
  314.  
  315. /*
  316. **  USER_PROFILE
  317. **
  318. **    Respond to a user profile request.
  319. **
  320. **  Parameters:
  321. **    sactx        Sambar Server Application context to release.
  322. **    saconn        Sambar Server User Connection handle.
  323. **    buffer        Profile attribute being queried.
  324. **    buflen        Length of the profile attribute.
  325. **    data        Buffer for the profile result 
  326. **                Note: A maximum of 512 bytes may be written to the data buffer.
  327. **
  328. **  Return Values:
  329. **    SA_SUCCESS | SA_FAIL
  330. */
  331. SA_RETCODE SA_PUBLIC
  332. user_profile(sactx, saconn, buffer, buflen, data)
  333. SA_CTX        *sactx;
  334. SA_CONN        *saconn;
  335. SA_CHAR        *buffer;
  336. SA_INT        buflen;
  337. SA_CHAR        *data;
  338. {
  339.     LOGIN_PROFILE    *profile;
  340.  
  341.     /* Get the user's profile handle                                     */
  342.     if (sa_conn_key(saconn, SA_GET, LOGIN_PROFILE_KEY, (SA_VOID **)&profile)
  343.         != SA_SUCCEED)
  344.     {
  345.         /* User never completed login                                    */
  346.         return (SA_FAIL);
  347.     }
  348.  
  349.     if (profile == (LOGIN_PROFILE *)NULL)
  350.     {
  351.         sa_log(sactx, "user_profile:  LOGIN_PROFILE_KEY returned NULL!");
  352.         return (SA_FAIL);
  353.     }
  354.  
  355.     /* 
  356.     ** Profile lookup
  357.     */
  358.     if ((buflen == 5) && (strncmp(buffer, "group", 5) == 0))
  359.     {
  360.         strcpy(data, profile->group);
  361.     }
  362.     else if ((buflen == 4) && (strncmp(buffer, "name", 4) == 0))
  363.     {
  364.         strcpy(data, profile->name);
  365.     }
  366.     else
  367.     {
  368.         SA_CHAR        tmp[512];
  369.  
  370.         sprintf(tmp, "Profile attribute '%s' not supported!", buffer);
  371.         sa_log(sactx, tmp);
  372.         return (SA_FAIL);
  373.     }
  374.  
  375.     return (SA_SUCCEED);
  376. }
  377.  
  378. /*
  379. **  USER_ADD
  380. **
  381. **    Add a new user
  382. **
  383. **  Parameters:
  384. **    sactx        Sambar Server context
  385. **    saconn        Sambar Server connection
  386. **    saparams    RPC Parameters
  387. **    infop        Error parameters
  388. **
  389. **  Returns:
  390. **    SA_SUCCEED | SA_FAIL
  391. */
  392. SA_RETCODE SA_PUBLIC
  393. user_add(sactx, saconn, saparams, infop)
  394. SA_CTX        *sactx;
  395. SA_CONN        *saconn;
  396. SA_PARAMS    *saparams;
  397. SA_INT        *infop;
  398. {
  399.     SA_CHAR        *data;
  400.     SA_INT        datalen;
  401.     SA_PASSWD    passwd;
  402.  
  403.     memset(&passwd, 0, sizeof(SA_PASSWD));
  404.     
  405.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  406.     {
  407.         *infop = SA_E_INVALIDDATA;
  408.         sa_log(sactx, "user_add(): Expected parameter 'password'!");
  409.         return (SA_FAIL);
  410.     }
  411.     
  412.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  413.     if (passwd.passwordlen > 0)
  414.         memcpy(passwd.password, data, passwd.passwordlen);
  415.  
  416.     if (sa_param(sactx, saparams, "group", &data, &datalen) != SA_SUCCEED)
  417.     {
  418.         *infop = SA_E_INVALIDDATA;
  419.         sa_log(sactx, "user_add(): Expected parameter 'group'!");
  420.         return (SA_FAIL);
  421.     }
  422.     
  423.     passwd.grouplen = MIN(datalen, SA_MAX_NAME);
  424.     if (passwd.grouplen > 0)
  425.         memcpy(passwd.group, data, passwd.grouplen);
  426.  
  427.     if (sa_param(sactx, saparams, "name", &data, &datalen) != SA_SUCCEED)
  428.     {
  429.         *infop = SA_E_INVALIDDATA;
  430.         sa_log(sactx, "user_add(): Expected parameter 'name'!");
  431.         return (SA_FAIL);
  432.     }
  433.     
  434.     passwd.namelen = MIN(datalen, SA_MAX_NAME);
  435.     if (passwd.namelen > 0)
  436.         memcpy(passwd.name, data, passwd.namelen);
  437.  
  438.     if (sa_param(sactx, saparams, "dir", &data, &datalen) != SA_SUCCEED)
  439.     {
  440.         *infop = SA_E_INVALIDDATA;
  441.         sa_log(sactx, "user_add(): Expected parameter 'dir'!");
  442.         return (SA_FAIL);
  443.     }
  444.     
  445.     passwd.dirlen = MIN(datalen, SA_MAX_NAME);
  446.     if (passwd.dirlen > 0)
  447.         memcpy(passwd.dir, data, passwd.dirlen);
  448.  
  449.     if (sa_param(sactx, saparams, "ftpprivs", &data, &datalen) != SA_SUCCEED)
  450.     {
  451.         *infop = SA_E_INVALIDDATA;
  452.         sa_log(sactx, "user_add(): Expected parameter 'ftpprivs'!");
  453.         return (SA_FAIL);
  454.     }
  455.  
  456.     passwd.ftpprivs = atol(data);
  457.     
  458.     if (sa_param(sactx, saparams, "nntpprivs", &data, &datalen) != SA_SUCCEED)
  459.     {
  460.         *infop = SA_E_INVALIDDATA;
  461.         sa_log(sactx, "user_add(): Expected parameter 'nttpprivs'!");
  462.         return (SA_FAIL);
  463.     }
  464.     
  465.     passwd.nntpprivs = atol(data);
  466.  
  467.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  468.     {
  469.         *infop = SA_E_INVALIDDATA;
  470.         sa_log(sactx, "user_add(): Expected parameter 'username'!");
  471.         return (SA_FAIL);
  472.     }
  473.  
  474.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  475.     {
  476.         *infop = SA_E_INVALIDDATA;
  477.         sa_log(sactx, "user_add(): 'username' field left NULL!");
  478.         return (SA_FAIL);
  479.     }
  480.  
  481.     if (sa_passwd_add(sactx, data, datalen, &passwd) != SA_SUCCEED)
  482.     {
  483.         *infop = SA_E_ALREADYDEFINED;
  484.         sa_log(sactx, "user_add(): sa_passwd_add() failed!");
  485.         return (SA_FAIL);
  486.     }
  487.  
  488.     return (SA_SUCCEED);
  489. }
  490.  
  491. /*
  492. **  USER_UPDATE
  493. **
  494. **    Update an existing user
  495. **
  496. **  Parameters:
  497. **    sactx        Sambar Server context
  498. **    saconn        Sambar Server connection
  499. **    saparams    RPC Parameters
  500. **    infop        Error parameters
  501. **
  502. **  Returns:
  503. **    SA_SUCCEED | SA_FAIL
  504. */
  505. SA_RETCODE SA_PUBLIC
  506. user_update(sactx, saconn, saparams, infop)
  507. SA_CTX        *sactx;
  508. SA_CONN        *saconn;
  509. SA_PARAMS    *saparams;
  510. SA_INT        *infop;
  511. {
  512.     SA_CHAR        *data;
  513.     SA_INT        datalen;
  514.     SA_PASSWD    passwd;
  515.  
  516.     memset(&passwd, 0, sizeof(SA_PASSWD));
  517.  
  518.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  519.     {
  520.         *infop = SA_E_INVALIDDATA;
  521.         sa_log(sactx, "user_update(): Expected parameter 'password'!");
  522.         return (SA_FAIL);
  523.     }
  524.     
  525.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  526.     if (passwd.passwordlen > 0)
  527.         memcpy(passwd.password, data, passwd.passwordlen);
  528.  
  529.     if (sa_param(sactx, saparams, "group", &data, &datalen) != SA_SUCCEED)
  530.     {
  531.         *infop = SA_E_INVALIDDATA;
  532.         sa_log(sactx, "user_update(): Expected parameter 'group'!");
  533.         return (SA_FAIL);
  534.     }
  535.     
  536.     passwd.grouplen = MIN(datalen, SA_MAX_NAME);
  537.     if (passwd.grouplen > 0)
  538.         memcpy(passwd.group, data, passwd.grouplen);
  539.  
  540.     if (sa_param(sactx, saparams, "name", &data, &datalen) != SA_SUCCEED)
  541.     {
  542.         *infop = SA_E_INVALIDDATA;
  543.         sa_log(sactx, "user_update(): Expected parameter 'name'!");
  544.         return (SA_FAIL);
  545.     }
  546.     
  547.     passwd.namelen = MIN(datalen, SA_MAX_NAME);
  548.     if (passwd.namelen > 0)
  549.         memcpy(passwd.name, data, passwd.namelen);
  550.  
  551.     if (sa_param(sactx, saparams, "dir", &data, &datalen) != SA_SUCCEED)
  552.     {
  553.         *infop = SA_E_INVALIDDATA;
  554.         sa_log(sactx, "user_update(): Expected parameter 'dir'!");
  555.         return (SA_FAIL);
  556.     }
  557.     
  558.     passwd.dirlen = MIN(datalen, SA_MAX_NAME);
  559.     if (passwd.dirlen > 0)
  560.         memcpy(passwd.dir, data, passwd.dirlen);
  561.  
  562.     if (sa_param(sactx, saparams, "ftpprivs", &data, &datalen) != SA_SUCCEED)
  563.     {
  564.         *infop = SA_E_INVALIDDATA;
  565.         sa_log(sactx, "user_update(): Expected parameter 'ftpprivs'!");
  566.         return (SA_FAIL);
  567.     }
  568.     
  569.     passwd.ftpprivs = atol(data);
  570.  
  571.     if (sa_param(sactx, saparams, "nntpprivs", &data, &datalen) != SA_SUCCEED)
  572.     {
  573.         *infop = SA_E_INVALIDDATA;
  574.         sa_log(sactx, "user_update(): Expected parameter 'nntpprivs'!");
  575.         return (SA_FAIL);
  576.     }
  577.     
  578.     passwd.nntpprivs = atol(data);
  579.  
  580.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  581.     {
  582.         *infop = SA_E_INVALIDDATA;
  583.         sa_log(sactx, "user_update(): Expected parameter 'username'!");
  584.         return (SA_FAIL);
  585.     }
  586.  
  587.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  588.     {
  589.         *infop = SA_E_INVALIDDATA;
  590.         sa_log(sactx, "user_update(): 'username' field left NULL!");
  591.         return (SA_FAIL);
  592.     }
  593.  
  594.     if (sa_passwd_update(sactx, data, datalen, &passwd) != SA_SUCCEED)
  595.     {
  596.         *infop = SA_E_ALREADYDEFINED;
  597.         sa_log(sactx, "user_update(): sa_passwd_update() failed!");
  598.         return (SA_FAIL);
  599.     }
  600.  
  601.     return (SA_SUCCEED);
  602. }
  603.  
  604. /*
  605. **  USER_DELETE
  606. **
  607. **    Delete an existing user
  608. **
  609. **  Parameters:
  610. **    sactx        Sambar Server context
  611. **    saconn        Sambar Server connection
  612. **    saparams    RPC Parameters
  613. **    infop        Error parameters
  614. **
  615. **  Returns:
  616. **    SA_SUCCEED | SA_FAIL
  617. */
  618. SA_RETCODE SA_PUBLIC
  619. user_delete(sactx, saconn, saparams, infop)
  620. SA_CTX        *sactx;
  621. SA_CONN        *saconn;
  622. SA_PARAMS    *saparams;
  623. SA_INT        *infop;
  624. {
  625.     SA_INT        datalen;
  626.     SA_CHAR        *data;
  627.  
  628.     if (sa_param(sactx, saparams, "username", &data, &datalen) != SA_SUCCEED)
  629.     {
  630.         *infop = SA_E_INVALIDDATA;
  631.         sa_log(sactx, "user_delete(): Expected parameter 'username'!");
  632.         return (SA_FAIL);
  633.     }
  634.  
  635.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  636.     {
  637.         *infop = SA_E_INVALIDDATA;
  638.         sa_log(sactx, "user_delete(): 'username' field left NULL!");
  639.         return (SA_FAIL);
  640.     }
  641.  
  642.     (SA_VOID)sa_passwd_delete(sactx, data, datalen);
  643.  
  644.     return (SA_SUCCEED);
  645. }
  646.  
  647. /*
  648. **  USER_SELECT
  649. **
  650. **    List all users for selection.
  651. **
  652. **  Parameters:
  653. **    sactx        Sambar Server context
  654. **    saconn        Sambar Server connection
  655. **    saparams    RPC Parameters
  656. **    infop        Error parameters
  657. **
  658. **  Returns:
  659. **    SA_SUCCEED | SA_FAIL
  660. **
  661. **  Notes:
  662. **    This list is truncated at 200 names.
  663. */
  664. SA_RETCODE SA_PUBLIC
  665. user_select(sactx, saconn, saparams, infop)
  666. SA_CTX        *sactx;
  667. SA_CONN        *saconn;
  668. SA_PARAMS    *saparams;
  669. SA_INT        *infop;
  670. {
  671.     SA_INT            i;
  672.     SA_BOOL            selected;
  673.     SA_INT            usernamelen;
  674.     SA_INT            numusers;
  675.     SA_CHAR            *username;
  676.     SA_USER            users[200];
  677.     SA_CHAR            buffer[256];
  678.  
  679.     /* If a username is provided make it SELECTED in the OPTION list    */
  680.     (SA_VOID)sa_param(sactx, saparams, "username", &username, &usernamelen);
  681.  
  682.     if (sa_passwd_list(sactx, users, 200, &numusers) != SA_SUCCEED)
  683.     {
  684.         sa_log(sactx, "user_select(): failure retrieving names list!");
  685.         return (SA_FAIL);
  686.     }
  687.  
  688.     /* We could sort the names alphabetically at this point...            */
  689.  
  690.     /* Display the list of users.                                        */
  691.     for (i = 0; i < numusers; i++)
  692.     {
  693.         selected = 0;
  694.         if ((users[i].usernamelen == usernamelen) &&
  695.             (memcmp(username, users[i].username, usernamelen) == 0))
  696.         {
  697.             selected = 1;
  698.         }
  699.  
  700.         sprintf(buffer, "<OPTION %s>%s\n", (selected ? "SELECTED" : ""),
  701.                 users[i].username);
  702.  
  703.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  704.             return (SA_FAIL);
  705.     }
  706.  
  707.     return (SA_SUCCEED);
  708. }
  709.  
  710. /*
  711. **  USER_LIST
  712. **
  713. **    List all users for delete or update.
  714. **
  715. **  Parameters:
  716. **    sactx        Sambar Server context
  717. **    saconn        Sambar Server connection
  718. **    saparams    RPC Parameters
  719. **    infop        Error parameters
  720. **
  721. **  Returns:
  722. **    SA_SUCCEED | SA_FAIL
  723. **
  724. **  Notes:
  725. **    This list is truncated at 200 names.
  726. **    List users by group...
  727. */
  728. SA_RETCODE SA_PUBLIC
  729. user_list(sactx, saconn, saparams, infop)
  730. SA_CTX        *sactx;
  731. SA_CONN        *saconn;
  732. SA_PARAMS    *saparams;
  733. SA_INT        *infop;
  734. {
  735.     SA_INT            i;
  736.     SA_INT            j;
  737.     SA_INT            sysadminlen;
  738.     SA_INT            numusers;
  739.     SA_INT            numgroups;
  740.     SA_GROUP        groups[100];
  741.     SA_USER            users[200];
  742.     SA_CHAR            sysadmin[SA_MAX_NAME + 1];
  743.     SA_CHAR            buffer[256];
  744.  
  745.     /* Get the sysadmin user (disallow deletes)                            */
  746.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_SYSADMIN, (SA_BYTE *)sysadmin,
  747.         SA_MAX_NAME, &sysadminlen) != SA_SUCCEED)
  748.     {
  749.         sa_log(sactx, "user_list(): failure retrieving system admin user!");
  750.         return (SA_FAIL);
  751.     }
  752.  
  753.     if (sa_passwd_list(sactx, users, 200, &numusers) != SA_SUCCEED)
  754.     {
  755.         sa_log(sactx, "user_list(): failure retrieving names list!");
  756.         return (SA_FAIL);
  757.     }
  758.  
  759.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  760.     {
  761.         sa_log(sactx, "user_list(): failure retrieving groups list!");
  762.         return (SA_FAIL);
  763.     }
  764.  
  765.     /* We could sort the list alphabetically at this point.                */
  766.  
  767.     /*
  768.     ** Display the users by "group".
  769.     ** Zero the usernamelen after displaying so we can put the rest in
  770.     ** the "other" list.
  771.     */
  772.     for (j = 0; j < numgroups; j++)
  773.     {
  774.         sprintf(buffer, "<FONT SIZE=+1 COLOR=#990033>%s</FONT><BLOCKQUOTE>\n",
  775.             groups[j].name);
  776.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  777.             return (SA_FAIL);
  778.         
  779.         /* Display the users in that group.                                */
  780.         for (i = 0; i < numusers; i++)
  781.         {
  782.             if ((users[i].usernamelen > 0) && 
  783.                 (users[i].grouplen == groups[j].namelen) &&
  784.                 (memcmp(users[i].group, groups[j].name, users[i].grouplen)==0))
  785.             {
  786.                 /* Make sure we don't display the user twice.            */
  787.                 users[i].usernamelen = 0;
  788.  
  789.                 if ((users[i].usernamelen != sysadminlen) ||
  790.                     (strncmp(sysadmin, users[i].username, sysadminlen) != 0))
  791.                 {
  792.                     sprintf(buffer, 
  793.                         "<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",
  794.                         users[i].username);
  795.  
  796.                     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  797.                         return (SA_FAIL);
  798.                 }
  799.  
  800.                 sprintf(buffer, 
  801.                     "<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",
  802.                     users[i].username, users[i].username);
  803.  
  804.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  805.                     return (SA_FAIL);
  806.             }
  807.         }
  808.  
  809.         if (sa_conn_send(saconn, "</BLOCKQUOTE>", SA_NULLTERM) != SA_SUCCEED)
  810.             return (SA_FAIL);
  811.     }
  812.  
  813.     /* Display the "other" group                                        */
  814.     sprintf(buffer, "<FONT SIZE=+1 COLOR=#990066>%s</FONT><BLOCKQUOTE>\n", 
  815.         SA_DEFAULT_GROUP);
  816.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  817.         return (SA_FAIL);
  818.         
  819.     /* Display the users in that group.                                    */
  820.     for (i = 0; i < numusers; i++)
  821.     {
  822.         /* Display all users not in any other group.                    */
  823.         if (users[i].usernamelen > 0)
  824.         {
  825.             if ((users[i].usernamelen != sysadminlen) ||
  826.                 (strncmp(sysadmin, users[i].username, sysadminlen) != 0))
  827.             {
  828.                 sprintf(buffer, 
  829.                     "<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",
  830.                     users[i].username);
  831.  
  832.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  833.                     return (SA_FAIL);
  834.             }
  835.  
  836.             sprintf(buffer, 
  837.                 "<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",
  838.                 users[i].username, users[i].username);
  839.  
  840.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  841.                 return (SA_FAIL);
  842.         }
  843.  
  844.     }
  845.  
  846.     if (sa_conn_send(saconn, "</BLOCKQUOTE>\n", SA_NULLTERM) != SA_SUCCEED)
  847.         return (SA_FAIL);
  848.  
  849.     return (SA_SUCCEED);
  850. }
  851.  
  852. /*
  853. **  USER_PASSWD
  854. **
  855. **    Update a user' password.
  856. **
  857. **  Parameters:
  858. **    sactx        Sambar Server context
  859. **    saconn        Sambar Server connection
  860. **    saparams    RPC Parameters
  861. **    infop        Error parameters
  862. **
  863. **  Returns:
  864. **    SA_SUCCEED | SA_FAIL
  865. */
  866. SA_RETCODE SA_PUBLIC
  867. user_passwd(sactx, saconn, saparams, infop)
  868. SA_CTX        *sactx;
  869. SA_CONN        *saconn;
  870. SA_PARAMS    *saparams;
  871. SA_INT        *infop;
  872. {
  873.     SA_CHAR        *data;
  874.     SA_INT        datalen;
  875.     SA_CHAR        *username;
  876.     SA_INT        usernamelen;
  877.     SA_PASSWD    passwd;
  878.  
  879.     /* What username is being updated?                                    */
  880.     if (sa_param(sactx, saparams, "username", &username, &usernamelen) 
  881.         != SA_SUCCEED)
  882.     {
  883.         *infop = SA_E_INVALIDDATA;
  884.         sa_log(sactx, "user_passwd(): Expected parameter 'username'!");
  885.         return (SA_FAIL);
  886.     }
  887.  
  888.     if ((usernamelen == 0) || (usernamelen > SA_MAX_NAME))
  889.     {
  890.         *infop = SA_E_INVALIDDATA;
  891.         sa_log(sactx, "user_update(): 'username' field left NULL!");
  892.         return (SA_FAIL);
  893.     }
  894.  
  895.     /* Lookup the username provided for update.                            */
  896.     if (sa_passwd_lookup(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  897.     {
  898.         *infop = SA_E_INVALIDDATA;
  899.         sa_log(sactx, "user_passwd(): sa_passwd_lookup() failed!");
  900.         return (SA_FAIL);
  901.     }
  902.  
  903.     /* Make sure that the password is valid.                        */
  904.     if (sa_param(sactx, saparams, "password", &data, &datalen) != SA_SUCCEED)
  905.     {
  906.         *infop = SA_E_INVALIDDATA;
  907.         sa_log(sactx, "user_passwd(): Expected parameter 'password'!");
  908.         return (SA_FAIL);
  909.     }
  910.     
  911.     /* Compare with the existing password.                            */
  912.     if (datalen != passwd.passwordlen)
  913.     {    
  914.         *infop = SA_E_INVALIDDATA;
  915.         sa_log(sactx, "user_passwd(): Invalid password provided.");
  916.         return (SA_FAIL);
  917.     }
  918.     
  919.     if (datalen > 0)
  920.     {
  921.         if (memcmp(passwd.password, data, datalen) != 0)
  922.         {
  923.             *infop = SA_E_INVALIDDATA;
  924.             sa_log(sactx, "user_passwd(): Invalid password provided.");
  925.             return (SA_FAIL);
  926.         }
  927.     }
  928.  
  929.     /* Get the new password.                                        */
  930.     if (sa_param(sactx, saparams, "newpasswd", &data, &datalen) != SA_SUCCEED)
  931.     {
  932.         *infop = SA_E_INVALIDDATA;
  933.         sa_log(sactx, "user_passwd(): Expected parameter 'newpasswd'!");
  934.         return (SA_FAIL);
  935.     }
  936.     
  937.     passwd.passwordlen = MIN(datalen, SA_MAX_NAME);
  938.     if (passwd.passwordlen > 0)
  939.         memcpy(passwd.password, data, passwd.passwordlen);
  940.  
  941.     if (sa_passwd_update(sactx, username, usernamelen, &passwd) != SA_SUCCEED)
  942.     {
  943.         sa_log(sactx, "user_passwd(): sa_passwd_update() failed!");
  944.         return (SA_FAIL);
  945.     }
  946.  
  947.     return (SA_SUCCEED);
  948. }
  949.  
  950. /*
  951. **  USER_PROP
  952. **
  953. **    Lookup and return a single user property.
  954. **
  955. **  Parameters:
  956. **    sactx        Sambar Server context
  957. **    saconn        Sambar Server connection
  958. **    saparams    RPC Parameters
  959. **    infop        Error parameters
  960. **
  961. **  Return Values:
  962. **    SA_SUCCESS | SA_FAIL
  963. */
  964. SA_RETCODE SA_PUBLIC
  965. user_prop(sactx, saconn, saparams, infop)
  966. SA_CTX        *sactx;
  967. SA_CONN        *saconn;
  968. SA_PARAMS    *saparams;
  969. SA_INT        *infop;
  970. {
  971.     SA_PASSWD            passwd;
  972.     SA_INT                userlen;
  973.     SA_CHAR                *user;
  974.     SA_INT                proplen;
  975.     SA_CHAR                *prop;
  976.     SA_CHAR                buffer[256];
  977.  
  978.     /* Get the page to direct to for user update                        */
  979.     if (sa_param(sactx, saparams, "username", &user, &userlen) != SA_SUCCEED)
  980.     {
  981.         *infop = SA_E_INVALIDDATA;
  982.         sa_log(sactx, "user_prop(): Expected parameter 'username'!");
  983.         return (SA_FAIL);
  984.     }
  985.  
  986.     if ((userlen == 0) || (userlen > SA_MAX_NAME))
  987.     {
  988.         *infop = SA_E_INVALIDDATA;
  989.         sa_log(sactx, "user_prop(): 'username' field left NULL!");
  990.         return (SA_FAIL);
  991.     }
  992.  
  993.     /* Get the property being looked up.                                */
  994.     if (sa_param(sactx, saparams, "prop", &prop, &proplen) != SA_SUCCEED)
  995.     {
  996.         *infop = SA_E_INVALIDDATA;
  997.         sa_log(sactx, "user_prop(): Expected parameter 'prop'!");
  998.         return (SA_FAIL);
  999.     }
  1000.  
  1001.     if ((proplen == 0) || (proplen > SA_MAX_NAME))
  1002.     {
  1003.         *infop = SA_E_INVALIDDATA;
  1004.         sa_log(sactx, "user_prop(): 'prop' field left NULL!");
  1005.         return (SA_FAIL);
  1006.     }
  1007.  
  1008.     if (sa_passwd_lookup(sactx, user, userlen, &passwd) != SA_SUCCEED)
  1009.     {
  1010.         sprintf(buffer, "User lookup for '%s' failed.", user);
  1011.         sa_log(sactx, buffer);
  1012.         *infop = SA_E_INVALIDDATA;
  1013.         return (SA_FAIL);
  1014.     }
  1015.  
  1016.     /* Lookup and return the appropriate property                        */
  1017.     if (strcmp(prop, "group") == 0)
  1018.     {
  1019.         if (sa_conn_send(saconn, passwd.group, passwd.grouplen) != SA_SUCCEED)
  1020.             return (SA_FAIL);
  1021.     }
  1022.     else if (strcmp(prop, "password") == 0)
  1023.     {
  1024.         if (sa_conn_send(saconn, passwd.password, passwd.passwordlen) 
  1025.             != SA_SUCCEED)
  1026.         {
  1027.             return (SA_FAIL);
  1028.         }
  1029.     }
  1030.     else if (strcmp(prop, "name") == 0)
  1031.     {
  1032.         if (sa_conn_send(saconn, passwd.name, passwd.namelen) != SA_SUCCEED)
  1033.             return (SA_FAIL);
  1034.     }
  1035.     else if (strcmp(prop, "dir") == 0)
  1036.     {
  1037.         if (sa_conn_send(saconn, passwd.dir, passwd.dirlen) != SA_SUCCEED)
  1038.             return (SA_FAIL);
  1039.     }
  1040.     else if (strcmp(prop, "ftpprivs") == 0)
  1041.     {
  1042.         if (sa_param(sactx, saparams, "checked", &prop, &proplen) == SA_SUCCEED)
  1043.         {
  1044.             int        tmp;
  1045.  
  1046.             tmp = 0;
  1047.             if (proplen > 0)
  1048.                 tmp = atoi(prop);
  1049.         
  1050.             if (tmp == passwd.ftpprivs)
  1051.             {
  1052.                 if (sa_conn_send(saconn, "CHECKED", SA_NULLTERM) != SA_SUCCEED)
  1053.                     return (SA_FAIL);
  1054.             }
  1055.         }
  1056.         else
  1057.         {
  1058.             sprintf(buffer, "%ld", passwd.ftpprivs);
  1059.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1060.                 return (SA_FAIL);
  1061.         }
  1062.     }
  1063.     else if (strcmp(prop, "nntpprivs") == 0)
  1064.     {
  1065.         if (sa_param(sactx, saparams, "checked", &prop, &proplen) == SA_SUCCEED)
  1066.         {
  1067.             int        tmp;
  1068.  
  1069.             tmp = 0;
  1070.             if (proplen > 0)
  1071.                 tmp = atoi(prop);
  1072.         
  1073.             if (tmp == passwd.nntpprivs)
  1074.             {
  1075.                 if (sa_conn_send(saconn, "CHECKED", SA_NULLTERM) != SA_SUCCEED)
  1076.                     return (SA_FAIL);
  1077.             }
  1078.         }
  1079.         else
  1080.         {
  1081.             sprintf(buffer, "%ld", passwd.nntpprivs);
  1082.             if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1083.                 return (SA_FAIL);
  1084.         }
  1085.     }
  1086.     else 
  1087.     {
  1088.         sprintf(buffer, "User lookup for property '%s' failed.", prop);
  1089.         sa_log(sactx, buffer);
  1090.         *infop = SA_E_INVALIDDATA;
  1091.         return (SA_FAIL);
  1092.     }
  1093.  
  1094.     return (SA_SUCCEED);
  1095. }
  1096.  
  1097. /*
  1098. **  FTP_CONNECT
  1099. **
  1100. **    Process an FTP Connect request. Verify the username/password against 
  1101. **    the Sambar Server password interfaces and return the root directory
  1102. **    and priviledges.
  1103. **
  1104. **  Parameters:
  1105. **    sactx            Sambar Server Application context to release.
  1106. **    saconn            Sambar Server User Connection handle.
  1107. **    username        Name of the user logging in.
  1108. **    usernamelen        Length of the user name
  1109. **    password        Password of the user logging in.
  1110. **    passwordlen        Length of the password.
  1111. **    ftpresp            FTP response structure.
  1112. **
  1113. **  Return Values:
  1114. **    SA_SUCCESS         Login Accepted.
  1115. **    SA_FAIL            Login Denied.
  1116. */
  1117. SA_RETCODE SA_PUBLIC
  1118. ftp_connect(sactx, name, namelen, password, passwordlen, ftpresp)
  1119. SA_CTX        *sactx;
  1120. SA_CHAR        *name;
  1121. SA_INT        namelen;
  1122. SA_CHAR        *password;
  1123. SA_INT        passwordlen;
  1124. SA_FTP        *ftpresp;
  1125. {
  1126.     SA_PASSWD            passwd;
  1127.     SA_CHAR                buffer[512];
  1128.  
  1129.     if (sa_passwd_lookup(sactx, name, namelen, &passwd) != SA_SUCCEED)
  1130.     {
  1131.         sprintf(buffer, "FTP login for user '%s' failed.", name);
  1132.         sa_log(sactx, buffer);
  1133.         return (SA_FAIL);
  1134.     }
  1135.  
  1136.     /* Verify the passwords are the same                                */
  1137.     if ((passwd.passwordlen != passwordlen) ||
  1138.         (strncmp(passwd.password, password, passwordlen) != 0))
  1139.     {
  1140.         /* Special case for anonymous user - NULL password match OK        */
  1141.         if ((namelen != 9) || (strncmp(name, "anonymous", 9) != 0))
  1142.         {
  1143.             sprintf(buffer, "FTP login for user '%s' failed - bad password (%s)", 
  1144.                 name, password);
  1145.             sa_log(sactx, buffer);
  1146.             return (SA_FAIL);
  1147.         }
  1148.     }
  1149.  
  1150.     /* Return the directory and access priviledges                    */
  1151.     ftpresp->privs = passwd.ftpprivs;
  1152.     ftpresp->dirlen = passwd.dirlen;
  1153.     if (ftpresp->dirlen > 0)
  1154.         strncpy(ftpresp->dir, passwd.dir, ftpresp->dirlen);
  1155.  
  1156.     ftpresp->dir[ftpresp->dirlen] = '\0';
  1157.  
  1158. #ifdef DEBUG
  1159.     sprintf(buffer, "FTP User '%s' logged in.", name);
  1160.     sa_log(sactx, buffer);
  1161. #endif    /* DEBUG */
  1162.  
  1163.     return (SA_SUCCEED);
  1164. }
  1165.  
  1166. /*
  1167. **  GROUP_ADD
  1168. **
  1169. **    Add a new group
  1170. **
  1171. **  Parameters:
  1172. **    sactx        Sambar Server context
  1173. **    saconn        Sambar Server connection
  1174. **    saparams    RPC Parameters
  1175. **    infop        Error parameters
  1176. **
  1177. **  Returns:
  1178. **    SA_SUCCEED | SA_FAIL
  1179. */
  1180. SA_RETCODE SA_PUBLIC
  1181. group_add(sactx, saconn, saparams, infop)
  1182. SA_CTX        *sactx;
  1183. SA_CONN        *saconn;
  1184. SA_PARAMS    *saparams;
  1185. SA_INT        *infop;
  1186. {
  1187.     SA_CHAR        *data;
  1188.     SA_INT        datalen;
  1189.  
  1190.     if (sa_param(sactx, saparams, "groupname", &data, &datalen) != SA_SUCCEED)
  1191.     {
  1192.         *infop = SA_E_INVALIDDATA;
  1193.         sa_log(sactx, "group_add(): Expected parameter 'groupname'!");
  1194.         return (SA_FAIL);
  1195.     }
  1196.     
  1197.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  1198.     {
  1199.         *infop = SA_E_INVALIDDATA;
  1200.         sa_log(sactx, "group_add(): 'name' field left NULL!");
  1201.         return (SA_FAIL);
  1202.     }
  1203.  
  1204.     /* Can't create the group "other"                                    */
  1205.     if ((datalen == 5) && 
  1206.         (memcmp(data, SA_DEFAULT_GROUP, strlen(SA_DEFAULT_GROUP)) == 0))
  1207.     {
  1208.         *infop = SA_E_INVALIDDATA;
  1209.         sa_log(sactx, "group_add(): 'other' group already exists!");
  1210.         return (SA_FAIL);
  1211.     }
  1212.  
  1213.     if (sa_group_add(sactx, data, datalen) != SA_SUCCEED)
  1214.     {
  1215.         *infop = SA_E_ALREADYDEFINED;
  1216.         sa_log(sactx, "group_add(): sa_group_add() failed (already defined?)");
  1217.         return (SA_FAIL);
  1218.     }
  1219.  
  1220.     return (SA_SUCCEED);
  1221. }
  1222.  
  1223. /*
  1224. **  GROUP_DELETE
  1225. **
  1226. **    Delete an existing group
  1227. **
  1228. **  Parameters:
  1229. **    sactx        Sambar Server context
  1230. **    saconn        Sambar Server connection
  1231. **    saparams    RPC Parameters
  1232. **    infop        Error parameters
  1233. **
  1234. **  Returns:
  1235. **    SA_SUCCEED | SA_FAIL
  1236. **
  1237. **    Notes:
  1238. **    No users can belong to the group.
  1239. */
  1240. SA_RETCODE SA_PUBLIC
  1241. group_delete(sactx, saconn, saparams, infop)
  1242. SA_CTX        *sactx;
  1243. SA_CONN        *saconn;
  1244. SA_PARAMS    *saparams;
  1245. SA_INT        *infop;
  1246. {
  1247.     SA_INT        datalen;
  1248.     SA_CHAR        *data;
  1249.  
  1250.     if (sa_param(sactx, saparams, "groupname", &data, &datalen) != SA_SUCCEED)
  1251.     {
  1252.         *infop = SA_E_INVALIDDATA;
  1253.         sa_log(sactx, "group_delete(): Expected parameter 'groupname'!");
  1254.         return (SA_FAIL);
  1255.     }
  1256.  
  1257.     if ((datalen == 0) || (datalen > SA_MAX_NAME))
  1258.     {
  1259.         *infop = SA_E_INVALIDDATA;
  1260.         sa_log(sactx, "group_delete(): 'groupname' field left NULL!");
  1261.         return (SA_FAIL);
  1262.     }
  1263.  
  1264.     /* Can't delete the group "other"                                    */
  1265.     if ((datalen == 5) && 
  1266.         (memcmp(data, SA_DEFAULT_GROUP, strlen(SA_DEFAULT_GROUP)) == 0))
  1267.     {
  1268.         *infop = SA_E_INVALIDDATA;
  1269.         sa_log(sactx, "group_delete(): 'other' group cannot be deleted!");
  1270.         return (SA_FAIL);
  1271.     }
  1272.  
  1273.     /* Should only be allowed to do this if the group has no users.        */
  1274.     (SA_VOID)sa_group_delete(sactx, data, datalen);
  1275.  
  1276.     return (SA_SUCCEED);
  1277. }
  1278.  
  1279. /*
  1280. **  GROUP_SELECT
  1281. **
  1282. **    List all groups for selection.
  1283. **
  1284. **  Parameters:
  1285. **    sactx        Sambar Server context
  1286. **    saconn        Sambar Server connection
  1287. **    saparams    RPC Parameters
  1288. **    infop        Error parameters
  1289. **
  1290. **  Returns:
  1291. **    SA_SUCCEED | SA_FAIL
  1292. **
  1293. **  Notes:
  1294. **    This list is truncated at 100 names.
  1295. **    The group other always exists and is used for users with unrecognized
  1296. **    group names.
  1297. */
  1298. SA_RETCODE SA_PUBLIC
  1299. group_select(sactx, saconn, saparams, infop)
  1300. SA_CTX        *sactx;
  1301. SA_CONN        *saconn;
  1302. SA_PARAMS    *saparams;
  1303. SA_INT        *infop;
  1304. {
  1305.     SA_INT            i;
  1306.     SA_BOOL            found;
  1307.     SA_BOOL            selected;
  1308.     SA_INT            grouplen;
  1309.     SA_INT            userlen;
  1310.     SA_INT            numgroups;
  1311.     SA_CHAR            *user;
  1312.     SA_PASSWD        passwd;
  1313.     SA_CHAR            group[SA_MAX_NAME + 1];
  1314.     SA_GROUP        groups[100];
  1315.     SA_CHAR            buffer[256];
  1316.  
  1317.     /* If a name is provided make it SELECTED in the OPTION list        */
  1318.     userlen = 0;
  1319.     grouplen = 0;
  1320.     (SA_VOID)sa_param(sactx, saparams, "username", &user, &userlen);
  1321.  
  1322.     if (userlen > 0)
  1323.     {
  1324.         if (sa_passwd_lookup(sactx, user, userlen, &passwd) != SA_SUCCEED)
  1325.         {
  1326.             sprintf(buffer, "User lookup for '%s' failed.", user);
  1327.             sa_log(sactx, buffer);
  1328.             *infop = SA_E_INVALIDDATA;
  1329.             return (SA_FAIL);
  1330.         }
  1331.  
  1332.         grouplen = passwd.grouplen;
  1333.         if (grouplen > 0)
  1334.             memcpy(group, passwd.group, grouplen);
  1335.     }
  1336.  
  1337.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  1338.     {
  1339.         sa_log(sactx, "group_select(): failure retrieving groups list!");
  1340.         return (SA_FAIL);
  1341.     }
  1342.  
  1343.     /* We could sort the names alphabetically at this point...            */
  1344.  
  1345.     /* Display the list of groups.                                        */
  1346.     found = 0;
  1347.     for (i = 0; i < numgroups; i++)
  1348.     {
  1349.         selected = 0;
  1350.         if ((grouplen > 0) &&
  1351.             (groups[i].namelen == grouplen) &&
  1352.             (memcmp(group, groups[i].name, grouplen) == 0))
  1353.         {
  1354.             selected = 1;
  1355.             found = 1;
  1356.         }
  1357.  
  1358.         sprintf(buffer, "<OPTION %s>%s\n", (selected ? "SELECTED" : ""),
  1359.             groups[i].name);
  1360.  
  1361.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1362.             return (SA_FAIL);
  1363.     }
  1364.  
  1365.     /* The group "other" always exists.                                    */
  1366.     sprintf(buffer, "<OPTION %s>%s\n", (found ? "" : "SELECTED"),
  1367.         SA_DEFAULT_GROUP);
  1368.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1369.         return (SA_FAIL);
  1370.  
  1371.     return (SA_SUCCEED);
  1372. }
  1373.  
  1374. /*
  1375. **  GROUP_LIST
  1376. **
  1377. **    List all groups for delete.
  1378. **
  1379. **  Parameters:
  1380. **    sactx        Sambar Server context
  1381. **    saconn        Sambar Server connection
  1382. **    saparams    RPC Parameters
  1383. **    infop        Error parameters
  1384. **
  1385. **  Returns:
  1386. **    SA_SUCCEED | SA_FAIL
  1387. **
  1388. **  Notes:
  1389. **    This list is truncated at 100 names.
  1390. **    The group "other" always exists and is the default group.
  1391. */
  1392. SA_RETCODE SA_PUBLIC
  1393. group_list(sactx, saconn, saparams, infop)
  1394. SA_CTX        *sactx;
  1395. SA_CONN        *saconn;
  1396. SA_PARAMS    *saparams;
  1397. SA_INT        *infop;
  1398. {
  1399.     SA_INT            i;
  1400.     SA_INT            numgroups;
  1401.     SA_GROUP        groups[100];
  1402.     SA_CHAR            buffer[256];
  1403.  
  1404.     if (sa_group_list(sactx, groups, 100, &numgroups) != SA_SUCCEED)
  1405.     {
  1406.         sa_log(sactx, "group_list(): failure retrieving groups list!");
  1407.         return (SA_FAIL);
  1408.     }
  1409.  
  1410.     /* We could sort the list alphabetically at this point.                */
  1411.  
  1412.     /* Display the list of groups.                                        */
  1413.     for (i = 0; i < numgroups; i++)
  1414.     {
  1415.         sprintf(buffer, 
  1416.             "<A HREF=\"/session/delgroup?name=%s&RCpage=/sysadmin/usermgmt/grouplist.stm\" onClick=\"return confirmDelete()\"><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/trash.gif\"></A>\n",
  1417.             groups[i].name);
  1418.  
  1419.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1420.             return (SA_FAIL);
  1421.  
  1422.         sprintf(buffer, 
  1423.             "<A HREF=\"/sysadmin/usermgmt/groupusers.stm?RCSgroup=%s\" TARGET=body><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/info.gif\"> %s</A><BR>\n",
  1424.             groups[i].name, groups[i].name);
  1425.  
  1426.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1427.             return (SA_FAIL);
  1428.     }
  1429.  
  1430.     /* Add the group "other"                                            */
  1431.     sprintf(buffer,
  1432.         "<A HREF=\"/sysadmin/usermgmt/groupusers.stm?RCSgroup=%s\" TARGET=body><IMG border=0 HEIGHT=20 WIDTH=20 SRC=\"/sysimage/system/info.gif\"> %s</A><BR>\n",
  1433.         SA_DEFAULT_GROUP, SA_DEFAULT_GROUP);
  1434.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  1435.         return (SA_FAIL);
  1436.  
  1437.     return (SA_SUCCEED);
  1438. }
  1439.