Back to index

im-sdk  12.3.91
role-data-client.c
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <ctype.h>
00003 #include <string.h>
00004 #include <sys/types.h>
00005 #include <unistd.h>
00006 #include <time.h>
00007 #include <pwd.h>
00008 #include <sys/param.h>
00009 #include <sys/stat.h>
00010 #include <sys/mman.h>
00011 #include <fcntl.h>
00012 #include <errno.h>
00013 #include <sys/utsname.h>
00014 #if !defined(OS_ARCH) && defined(HAVE_SYSINFO) && defined(HAVE_SYS_SYSTEMINFO_H)
00015 #include <sys/systeminfo.h>
00016 #endif
00017 
00018 #include <iiimp.h>
00019 
00020 #include "input-method.h"
00021 #include "role-data-client.h"
00022 
00023 
00024 #define NODE_DEFAULT "localhost"
00025 #define NODE_KEY     "node="
00026 #define NODE_KEY_LEN (5)
00027 #define SERVICE_DEFAULT     "9010"
00028 #define SERVICE_KEY  "service="
00029 #define SERVICE_KEY_LEN     (8)
00030 
00031 #define SERVER_FILE         ".iiim/server"
00032 #define SERVER_FILE_LEN            (12)
00033 
00034 #define SERVER_COMPAT_FILE  ".iiimp"
00035 #define SERVER_COMPAT_FILE_LEN     (6)
00036 #define SERVER_COMPAT_KEY   "iiimp.server=iiimp://"
00037 #define SERVER_COMPAT_KEY_LEN      (21)
00038 
00039 #define CONFIG_DIR_BASE            ".iiim"
00040 #define CONFIG_DIR_AUTH            ".iiim/auth"
00041 #define CONFIG_FILE_PASSWD  ".iiim/auth/passwd"
00042 #define PASSWORD_FILE_LEN   (17)
00043 #define AUTH_PASSWORD_LEN   (32)
00044 #define HOME_ENV            "HOME"
00045 #define IIIM_SERVER_ENV            "IIIM_SERVER"
00046 
00047 #define CLIENT_TYPE         "generic IIIMP client"
00048 
00049 
00050 const char *
00051 iiimf_role_data_client_user_name(IIIMF_im * im)
00052 {
00053     return im->role_data.client->user_name;
00054 }
00055 
00056 
00057 const char *
00058 iiimf_role_data_client_home_dir(IIIMF_im * im)
00059 {
00060     return im->role_data.client->home_dir;
00061 }
00062 
00063 
00064 const char *
00065 iiimf_role_data_client_node(IIIMF_im * im)
00066 {
00067     return im->role_data.client->node;
00068 }
00069 
00070 
00071 const char *
00072 iiimf_role_data_client_server_node(IIIMF_im * im)
00073 {
00074     return im->role_data.client->server_node;
00075 }
00076 
00077 
00078 const char *
00079 iiimf_role_data_client_service(IIIMF_im * im)
00080 {
00081     return im->role_data.client->service;
00082 }
00083 
00084 
00085 #define POSITION_HEAD(p, n) \
00086        for (; 0 < n; --(n), (p)++) { \
00087               if ((' ' != *(p)) && ('\t' != *(p)) && \
00088                   ('\r' != *(p)) && ('\n' != *(p))) { \
00089                      break; \
00090               } \
00091        } \
00092        if ((0 < (n)) && ((',' == *(p)) || (';' == *(p)))) { \
00093               --(n); \
00094               (p)++; \
00095        } \
00096        for (; 0 < n; --(n), (p)++) { \
00097               if ((' ' != *(p)) && ('\t' != *(p)) && \
00098                   ('\r' != *(p)) && ('\n' != *(p))) { \
00099                      break; \
00100               } \
00101        }
00102 
00103 #define POSITION_TAIL(p, n) \
00104        for (; 0 < n; --(n), (p)++) { \
00105               if ((',' == *(p)) || (';' == *(p)) || \
00106                   (' ' == *(p)) || ('\t' == *(p)) || \
00107                   ('\r' == *(p)) || ('\n' == *(p))) { \
00108                      break; \
00109               } \
00110        }
00111 
00112 #define POSITION_TAIL_COMPAT(p, n) \
00113        for (; 0 < n; --(n), (p)++) { \
00114               if ((':' == *(p)) || ('\r' == *(p)) || ('\n' == *(p))) { \
00115                      break; \
00116               } \
00117        }
00118 
00119 
00120 static IIIMF_status
00121 get_param(
00122     const char **    buf,
00123     size_t *         nbyte,
00124     const char *     key,
00125     size_t           key_len,
00126     char **          param_ret)
00127 {
00128     const char *     b;
00129     const char *     p;
00130     size_t           n;
00131     size_t           m;
00132     size_t           len;
00133     char *           param;
00134 
00135     b = *buf;
00136     n = *nbyte;
00137 
00138     if (n < key_len) return IIIMF_STATUS_CONFIG;
00139 
00140     if (0 != strncasecmp(b, key, key_len)) {
00141        return IIIMF_STATUS_CONFIG;
00142     }
00143 
00144     b += key_len;
00145     n -= key_len;
00146     p = b;
00147     m = n;
00148 
00149     POSITION_TAIL(b, n);
00150 
00151     len = (m - n);
00152 
00153     param = (char *)malloc(len + 1);
00154     if (NULL == param) return IIIMF_STATUS_MALLOC;
00155 
00156     (void)memcpy(param, p, len);
00157     *(param + len) = '\0';
00158 
00159     *buf = b;
00160     *nbyte = n;
00161     *param_ret = param;
00162 
00163     return IIIMF_STATUS_SUCCESS;
00164 }
00165 
00166 
00167 static IIIMF_status
00168 get_param_compat(
00169     const char **    buf,
00170     size_t *         nbyte,
00171     const char *     key,
00172     size_t           key_len,
00173     char **          param_ret)
00174 {
00175     const char *     b;
00176     const char *     p;
00177     size_t           n;
00178     size_t           m;
00179     size_t           len;
00180     char *           param;
00181 
00182     b = *buf;
00183     n = *nbyte;
00184 
00185     if (n < key_len) return IIIMF_STATUS_CONFIG;
00186 
00187     if (0 != strncasecmp(b, key, key_len)) {
00188        return IIIMF_STATUS_CONFIG;
00189     }
00190 
00191     b += key_len;
00192     n -= key_len;
00193     p = b;
00194     m = n;
00195 
00196     POSITION_TAIL_COMPAT(b, n);
00197 
00198     len = (m - n);
00199 
00200     param = (char *)malloc(len + 1);
00201     if (NULL == param) return IIIMF_STATUS_MALLOC;
00202 
00203     (void)memcpy(param, p, len);
00204     *(param + len) = '\0';
00205 
00206     *buf = b;
00207     *nbyte = n;
00208     *param_ret = param;
00209 
00210     return IIIMF_STATUS_SUCCESS;
00211 }
00212 
00213 
00214 static IIIMF_status
00215 iiimf_role_data_client_file_server(IIIMF_role_data_client * client)
00216 {
00217     int                     fd;
00218     IIIMF_status     status;
00219     char *           server_file;
00220     size_t           server_file_len;
00221     size_t           home_dir_len;
00222     struct stat             st;
00223     int                     stat_ret;
00224     char *           pa;
00225     const char *     p;
00226     size_t           rest;
00227     char *           node;
00228     char *           service;
00229 
00230     home_dir_len = strlen(client->home_dir);
00231     server_file_len = (home_dir_len + 1 + SERVER_FILE_LEN);
00232 
00233     server_file = (char *)malloc(server_file_len + 1);
00234     if (NULL == server_file) {
00235        return IIIMF_STATUS_MALLOC;
00236     }
00237 
00238     (void)strcpy(server_file, client->home_dir);
00239     *(server_file + home_dir_len) = '/';
00240     (void)strcpy(server_file + home_dir_len + 1, SERVER_FILE);
00241 
00242     fd = open(server_file, O_RDONLY, 0);
00243     free(server_file);
00244     if (fd < 0) return IIIMF_STATUS_CONFIG;
00245 
00246     stat_ret = fstat(fd, &st);
00247     if (stat_ret < 0) {
00248        return IIIMF_STATUS_CONFIG;
00249     }
00250 
00251     pa = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
00252     (void)close(fd);
00253     if (NULL == pa) return IIIMF_STATUS_CONFIG;
00254 
00255     p = pa;
00256     rest = st.st_size;
00257 
00258     POSITION_HEAD(p, rest);
00259     if (rest < NODE_KEY_LEN) {
00260        (void)munmap(pa, st.st_size);
00261        return IIIMF_STATUS_CONFIG;
00262     }
00263 
00264     status = get_param(&p, &rest, NODE_KEY, NODE_KEY_LEN, &node);
00265     if (IIIMF_STATUS_SUCCESS != status) {
00266        (void)munmap(pa, st.st_size);
00267        return status;
00268     }
00269 
00270     client->server_node = node;
00271 
00272     POSITION_HEAD(p, rest);
00273     if (rest < SERVICE_KEY_LEN) {
00274        (void)munmap(pa, st.st_size);
00275        return IIIMF_STATUS_SUCCESS;
00276     }
00277 
00278     status = get_param(&p, &rest, SERVICE_KEY, SERVICE_KEY_LEN, &service);
00279 
00280     (void)munmap(pa, st.st_size);
00281 
00282     client->service = service;
00283 
00284     return IIIMF_STATUS_SUCCESS;
00285 }
00286 
00287 
00288 static IIIMF_status
00289 iiimf_role_data_client_file_compat_server(IIIMF_role_data_client * client)
00290 {
00291     int                     fd;
00292     IIIMF_status     status;
00293     char *           server_file;
00294     size_t           server_file_len;
00295     size_t           home_dir_len;
00296     struct stat             st;
00297     int                     stat_ret;
00298     char *           pa;
00299     const char *     p;
00300     size_t           rest;
00301     char *           node;
00302     char *           service;
00303 
00304     home_dir_len = strlen(client->home_dir);
00305     server_file_len = (home_dir_len + 1 + SERVER_COMPAT_FILE_LEN);
00306 
00307     server_file = (char *)malloc(server_file_len + 1);
00308     if (NULL == server_file) {
00309        return IIIMF_STATUS_MALLOC;
00310     }
00311 
00312     (void)strcpy(server_file, client->home_dir);
00313     *(server_file + home_dir_len) = '/';
00314     (void)strcpy(server_file + home_dir_len + 1, SERVER_COMPAT_FILE);
00315 
00316     fd = open(server_file, O_RDONLY, 0);
00317     free(server_file);
00318     if (fd < 0) return IIIMF_STATUS_CONFIG;
00319     stat_ret = fstat(fd, &st);
00320     if (stat_ret < 0) {
00321        return IIIMF_STATUS_CONFIG;
00322     }
00323 
00324     pa = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
00325     (void)close(fd);
00326     if (NULL == pa) return IIIMF_STATUS_CONFIG;
00327 
00328     p = pa;
00329     rest = st.st_size;
00330 
00331     while (0 < rest) {
00332        for (; 0 < rest; --rest, p++) {
00333            if (('\r' == *p) || ('\n' == *p)) {
00334               p += 1;
00335               rest -= 1;
00336               break;
00337            }
00338        }
00339        if (rest < SERVER_COMPAT_KEY_LEN) break;
00340 
00341        status = get_param_compat(&p, &rest,
00342                               SERVER_COMPAT_KEY,
00343                               SERVER_COMPAT_KEY_LEN,
00344                               &node);
00345        if (IIIMF_STATUS_SUCCESS == status) {
00346            client->server_node = node;
00347            p += 1;
00348            rest -= 1;
00349            break;
00350        }
00351     }
00352     if (NULL == client->server_node) {
00353        return IIIMF_STATUS_CONFIG;
00354     }
00355 
00356     status = get_param_compat(&p, &rest, "", 0, &service);
00357 
00358     (void)munmap(pa, st.st_size);
00359 
00360     if ('\0' == *service) {
00361        free(service);
00362        service = NULL;
00363     }
00364 
00365     if (IIIMF_STATUS_SUCCESS == status) {
00366        client->service = service;
00367     }
00368 
00369     return status;
00370 }
00371 
00372 
00373 static IIIMF_status
00374 iiimf_role_data_client_environ_server(IIIMF_role_data_client * client)
00375 {
00376     IIIMF_status     status;
00377     const char *     p;
00378     size_t           rest;
00379     char *           node;
00380     char *           service;
00381 
00382     p = getenv(IIIM_SERVER_ENV);
00383     if (NULL == p) return IIIMF_STATUS_FAIL;
00384 
00385     rest = strlen(p);
00386 
00387     status = get_param(&p, &rest, "", 0, &node);
00388     if (IIIMF_STATUS_SUCCESS != status) {
00389        return status;
00390     }
00391 
00392     client->server_node = node;
00393 
00394     POSITION_HEAD(p, rest);
00395 
00396     status = get_param(&p, &rest, "", 0, &service);
00397 
00398     client->service = service;
00399 
00400     return IIIMF_STATUS_SUCCESS;
00401 }
00402 
00403 
00404 IIIMF_status
00405 iiimf_im_client_type_set(
00406     IIIMF_im *              im,
00407     const char *     type)
00408 {
00409     char *    p;
00410     p = strdup(type);
00411     if (NULL == p) return IIIMF_STATUS_MALLOC;
00412     free(im->role_data.client->type);
00413     im->role_data.client->type = p;
00414     return IIIMF_STATUS_SUCCESS;
00415 }
00416 
00417 IIIMF_status
00418 iiimf_im_user_set(
00419     IIIMF_im *              im,
00420     const char *     username,
00421     const char *     password)
00422 {
00423     IIIMF_role_data_client *       client;
00424 
00425     client = im->role_data.client;
00426     if (username) {
00427        if (client->user_name) free(client->user_name);
00428        client->user_name = strdup(username);
00429     }
00430     if (password) {
00431        if (client->password) free(client->password);
00432        client->password = strdup(password);
00433     }
00434 
00435     return IIIMF_STATUS_SUCCESS;
00436 }
00437 
00438 
00439 IIIMF_status
00440 iiimf_role_data_client_new(
00441     const char *            server_node,
00442     const char *            service,
00443     IIIMF_role_data_client **      client_ret)
00444 {
00445     IIIMF_role_data_client *       client;
00446     struct passwd *         pwd;
00447     IIIMF_status            status;
00448     struct utsname          name;
00449 
00450     status = IIIMF_STATUS_CONFIG;
00451 
00452     client = (IIIMF_role_data_client *)malloc(sizeof (IIIMF_role_data_client));
00453     if (NULL == client) return IIIMF_STATUS_MALLOC;
00454 
00455     client->user_name = NULL;
00456     client->home_dir = NULL;
00457     client->node = NULL;
00458 
00459     client->server_node = ((NULL == server_node) ? NULL : strdup(server_node));
00460     client->service = ((NULL == service) ? NULL : strdup(service));
00461 
00462     client->type = strdup(CLIENT_TYPE);
00463 
00464     client->os_name = NULL;
00465     client->os_arch = NULL;
00466     client->os_version = NULL;
00467     client->X_display_name = NULL;
00468     client->X_server_vendor = NULL;
00469 
00470     pwd = getpwuid(geteuid());
00471     if (NULL == pwd) {
00472        iiimf_role_data_client_delete(client);
00473        return IIIMF_STATUS_CONFIG;
00474     }
00475 
00476     client->user_name = strdup(pwd->pw_name);
00477     client->home_dir = strdup(pwd->pw_dir);
00478 
00479     endpwent();
00480 
00481     if ((NULL == client->user_name) ||
00482        (NULL == client->home_dir) ||
00483        ((NULL != server_node) && (NULL == client->server_node)) ||
00484        ((NULL != service) && (NULL == client->service))) {
00485        iiimf_role_data_client_delete(client);
00486        return IIIMF_STATUS_MALLOC;
00487     }
00488 
00489     if (-1 == uname(&name)) {
00490        iiimf_role_data_client_delete(client);
00491        return IIIMF_STATUS_CONFIG;
00492     }
00493 
00494     client->node = strdup(name.nodename);
00495 
00496     client->os_name = strdup(name.sysname);
00497     client->os_version = strdup(name.release);
00498 
00499 #if defined(OS_ARCH)
00500     client->os_arch = strdup(OS_ARCH);
00501 #else /* !OS_ARCH */
00502 #if defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)
00503     ret = sysinfo(SI_ARCHITECTURE, arch, sizeof (arch));
00504     if (-1 == ret) {
00505        client->os_arch = NULL;
00506     } else if ((0 == strcmp(arch, "sparc")) ||
00507               (0 == strcmp(arch, "ppc"))) {
00508        client->os_arch = strdup(arch);
00509     } else if (0 == strcmp(arch, "i386")) {
00510        client->os_arch = strdup("x86");
00511     } else {
00512        client->os_arch = strdup("Unknown");
00513     }
00514 #else /* !HAVE_SYSINFO || !SI_ARCHITECTURE */
00515     client->os_arch = strdup("Unknown");
00516 #endif /* !HAVE_SYSINFO || !SI_ARCHITECTURE */
00517 #endif /* !OS_ARCH */
00518 
00519     if ((NULL == server_node) && (NULL == service)) {
00520        status = iiimf_role_data_client_environ_server(client);
00521        if (IIIMF_STATUS_SUCCESS != status) {
00522            status = iiimf_role_data_client_file_server(client);
00523        }
00524        if (IIIMF_STATUS_SUCCESS != status) {
00525            status = iiimf_role_data_client_file_compat_server(client);
00526        }
00527     }
00528 
00529     if (NULL == client->server_node) {
00530        client->server_node = strdup(NODE_DEFAULT);
00531     }
00532     if (NULL == client->service) {
00533        client->service = strdup(SERVICE_DEFAULT);
00534     }
00535     if ((NULL == client->node) || (NULL == client->service)) {
00536        iiimf_role_data_client_delete(client);
00537        return IIIMF_STATUS_MALLOC;
00538     }
00539 
00540     *client_ret = client;
00541 
00542     return IIIMF_STATUS_SUCCESS;
00543 }
00544 
00545 
00546 void
00547 iiimf_role_data_client_delete(IIIMF_role_data_client * client)
00548 {
00549     if (client->user_name) free(client->user_name);
00550     if (client->password) free(client->password);
00551     if (client->home_dir) free(client->home_dir);
00552     if (client->node) free(client->node);
00553     if (client->server_node) free(client->server_node);
00554     if (client->service) free(client->service);
00555     if (client->type) free(client->type);
00556     if (client->os_name) free(client->os_name);
00557     if (client->os_arch) free(client->os_arch);
00558     if (client->os_version) free(client->os_version);
00559     if (client->X_display_name) free(client->X_display_name);
00560     if (client->X_server_vendor) free(client->X_server_vendor);
00561 
00562     free(client);
00563 }
00564 
00565 
00566 static void
00567 auth_password_generate(char * password, size_t length)
00568 {
00569     int                     fd;
00570     unsigned int     seed;
00571     int                     c;
00572     int                     i;
00573     int                     r;
00574     unsigned int *   p;
00575     size_t           n;
00576     char *           c62;
00577 
00578     *(password + length) = '\0';
00579 
00580     c62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
00581     fd = open("/dev/random", O_RDONLY, 0);
00582     if (0 <= fd) {
00583        r = 0;
00584        n = ((sizeof (unsigned int)) * length);
00585        p = (unsigned int * )malloc(n);
00586        if (NULL != p) {
00587            r = read(fd, p, n);
00588        }
00589        (void)close(fd);
00590        if (r == length) {
00591            for (i = 0; i < length; i++) {
00592               *(password + i) = *(c62 + (*(p + i) % 62));
00593            }
00594            free(p);
00595            return;
00596        }
00597        free(p);
00598     }
00599 
00600     seed = (time(NULL) + getpid());
00601     srand(seed);
00602     for (i = 0; i < length; i++) {
00603        c = rand();
00604        *(password + i) = *(c62 + (c % 62));
00605     }
00606 
00607     return;
00608 }
00609 
00610 
00611 static int
00612 auth_password_file_init(char * password_file, size_t home_dir_len)
00613 {
00614     int              fd;
00615     char      pwd_buf[AUTH_PASSWORD_LEN + 1];
00616     struct stat      st;
00617     ssize_t   len;
00618 
00619     /* ${HOME}/.iiim */
00620     (void)strcpy(password_file + home_dir_len, CONFIG_DIR_BASE);
00621     if (0 != stat(password_file, &st)) {
00622        if (ENOENT != errno) return -1;
00623        if (0 != mkdir(password_file, 0777)) return -1;
00624     }
00625 
00626     /* ${HOME}/.iiim/auth */
00627     (void)strcpy(password_file + home_dir_len, CONFIG_DIR_AUTH);
00628     if (0 != stat(password_file, &st)) {
00629        if (ENOENT != errno) return -1;
00630        if (0 != mkdir(password_file, 0700)) return -1;
00631     }
00632 
00633     /* ${HOME}/.iiim/auth/password */
00634     (void)strcpy(password_file + home_dir_len, CONFIG_FILE_PASSWD);
00635     fd = open(password_file, O_CREAT | O_WRONLY, 0600);
00636     if (-1 == fd) return -1;
00637 
00638     auth_password_generate(pwd_buf, AUTH_PASSWORD_LEN);
00639 
00640     len = write(fd, pwd_buf, AUTH_PASSWORD_LEN + 1);
00641     (void)close(fd);
00642 
00643     if ((AUTH_PASSWORD_LEN + 1) == len) {
00644        return 0;
00645     } else {
00646        return -1;
00647     }
00648 }
00649 
00650 
00651 static int
00652 auth_password_file_open(const char * home_dir)
00653 {
00654     char *    password_file;
00655     char *    home_env;
00656     int              home_dir_len;
00657     int              len;
00658     struct stat      st;
00659     int              fd;
00660 
00661     password_file = NULL;
00662 
00663     if (NULL == home_dir) {
00664        home_env = getenv("HOME");
00665        if (NULL != home_env) {
00666            home_dir = home_env;
00667        }
00668        if (NULL == home_dir) {
00669            return -1;
00670        }
00671     }
00672 
00673     home_dir_len = strlen(home_dir);
00674     len = (home_dir_len + 1 + PASSWORD_FILE_LEN);
00675 
00676     password_file = malloc(len + 1);
00677     if (NULL == password_file) {
00678        return -1;
00679     }
00680 
00681     (void)strcpy(password_file, home_dir);
00682     *(password_file + home_dir_len) = '/';
00683     home_dir_len += 1;
00684     (void)strcpy(password_file + home_dir_len, CONFIG_FILE_PASSWD);
00685 
00686     if (0 != stat(password_file, &st)) {
00687        (void)auth_password_file_init(password_file, home_dir_len);
00688     }
00689 
00690     fd = open(password_file, O_RDONLY, 0);
00691     free(password_file);
00692 
00693     return fd;
00694 }
00695 
00696 
00697 IIIMF_status
00698 iiimf_role_data_client_auth_password(IIIMF_im * im, char ** password_ret)
00699 {
00700 
00701 #if 0
00702     char *    password;
00703     int              fd;
00704     int              len;
00705     int              i;
00706     char      pwd_buf[AUTH_PASSWORD_LEN + 1];
00707 
00708     if (im->role_data.client->password) {
00709        *password_ret = strdup(im->role_data.client->password);
00710        if (!(*password_ret)) return IIIMF_STATUS_MALLOC;
00711     } else {
00712        password = NULL;
00713        fd = -1;
00714 
00715        fd = auth_password_file_open(im->role_data.client->home_dir);
00716        if (-1 == fd) return IIIMF_STATUS_CONFIG;
00717 
00718        len = read(fd, pwd_buf, AUTH_PASSWORD_LEN);
00719        (void)close(fd);
00720 
00721        if (AUTH_PASSWORD_LEN != len) return IIIMF_STATUS_CONFIG;
00722 
00723        for (i = 0; i < AUTH_PASSWORD_LEN; i++) {
00724            if (0 == isalnum(pwd_buf[i])) {
00725               return IIIMF_STATUS_CONFIG;
00726            }
00727        }
00728        if (AUTH_PASSWORD_LEN != i) {
00729            return IIIMF_STATUS_CONFIG;
00730        }
00731 
00732        password = malloc(AUTH_PASSWORD_LEN + 1);
00733        if (NULL == password) return IIIMF_STATUS_MALLOC;
00734        (void)memcpy(password, pwd_buf, AUTH_PASSWORD_LEN);
00735        *(password + AUTH_PASSWORD_LEN) = '\0';
00736 
00737        *password_ret = password;
00738     }
00739 
00740 #endif
00741     *password_ret = strdup("");
00742     return IIIMF_STATUS_SUCCESS;
00743 }
00744 
00745 
00746 /* Local Variables: */
00747 /* c-file-style: "iiim-project" */
00748 /* End: */