From 2ca48d3740c40be2142ca7e7ad88aabdaa822c06 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Feb 2009 13:11:36 -0800 Subject: Fix printf type warning. Jeremy. --- source3/registry/reg_backend_db.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index fe5f192713..8ef83a19a1 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -550,8 +550,8 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr) (len+thistime)*2); if(buffer == NULL) { DEBUG(0, ("regdb_store_keys: Failed to realloc " - "memory of size [%d]\n", - (len+thistime)*2)); + "memory of size [%u]\n", + (unsigned int)(len+thistime)*2)); ret = false; goto done; } -- cgit From 669f2a02e29195aaba8cb2f3e50cb2ce66b904a6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Feb 2009 13:36:20 -0800 Subject: Fix printf warnings found on systems where time_t <> long int. Jeremy. --- source3/passdb/pdb_ldap.c | 16 ++++++++-------- source3/printing/tests/vlp.c | 2 +- source3/utils/smbget.c | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 043b620756..70a1c62bef 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1249,7 +1249,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), pdb_get_profile_path(sampass)); - if (asprintf(&temp, "%li", pdb_get_logon_time(sampass)) < 0) { + if (asprintf(&temp, "%li", (long int)pdb_get_logon_time(sampass)) < 0) { return false; } if (need_update(sampass, PDB_LOGONTIME)) @@ -1257,7 +1257,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp); SAFE_FREE(temp); - if (asprintf(&temp, "%li", pdb_get_logoff_time(sampass)) < 0) { + if (asprintf(&temp, "%li", (long int)pdb_get_logoff_time(sampass)) < 0) { return false; } if (need_update(sampass, PDB_LOGOFFTIME)) @@ -1265,7 +1265,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp); SAFE_FREE(temp); - if (asprintf(&temp, "%li", pdb_get_kickoff_time(sampass)) < 0) { + if (asprintf(&temp, "%li", (long int)pdb_get_kickoff_time(sampass)) < 0) { return false; } if (need_update(sampass, PDB_KICKOFFTIME)) @@ -1273,7 +1273,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp); SAFE_FREE(temp); - if (asprintf(&temp, "%li", pdb_get_pass_can_change_time_noncalc(sampass)) < 0) { + if (asprintf(&temp, "%li", (long int)pdb_get_pass_can_change_time_noncalc(sampass)) < 0) { return false; } if (need_update(sampass, PDB_CANCHANGETIME)) @@ -1281,7 +1281,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp); SAFE_FREE(temp); - if (asprintf(&temp, "%li", pdb_get_pass_must_change_time(sampass)) < 0) { + if (asprintf(&temp, "%li", (long int)pdb_get_pass_must_change_time(sampass)) < 0) { return false; } if (need_update(sampass, PDB_MUSTCHANGETIME)) @@ -1361,7 +1361,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, if (need_update(sampass, PDB_PASSLASTSET)) { if (asprintf(&temp, "%li", - pdb_get_pass_last_set_time(sampass)) < 0) { + (long int)pdb_get_pass_last_set_time(sampass)) < 0) { return false; } smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, @@ -1423,7 +1423,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, temp); SAFE_FREE(temp); - if (asprintf(&temp, "%li", badtime) < 0) { + if (asprintf(&temp, "%li", (long int)badtime) < 0) { return false; } smbldap_make_mod( @@ -5941,7 +5941,7 @@ static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods, smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID", sid_string_tos(sid)); smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet", - talloc_asprintf(talloc_tos(), "%li", time(NULL))); + talloc_asprintf(talloc_tos(), "%li", (long int)time(NULL))); smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaClearTextPassword", pwd); diff --git a/source3/printing/tests/vlp.c b/source3/printing/tests/vlp.c index 15459889e9..286e4a4b39 100644 --- a/source3/printing/tests/vlp.c +++ b/source3/printing/tests/vlp.c @@ -168,7 +168,7 @@ static int lpq_command(int argc, char **argv) job_list[i].size, (i == 0 && job_list[i].status == LPQ_QUEUED) ? LPQ_SPOOLING : job_list[i].status, - job_list[i].submit_time, job_list[i].owner, + (long int)job_list[i].submit_time, job_list[i].owner, job_list[i].jobname); job_count++; } diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index c062134a55..7c01f5db3a 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -487,7 +487,8 @@ static void clean_exit(void) { char bs[100]; human_readable(total_bytes, bs, sizeof(bs)); - if(!quiet)fprintf(stderr, "Downloaded %s in %lu seconds\n", bs, time(NULL) - total_start_time); + if(!quiet)fprintf(stderr, "Downloaded %s in %lu seconds\n", bs, + (unsigned long)(time(NULL) - total_start_time)); exit(0); } -- cgit From 6fbebb5369211b72545a1dd588bc6b9fa04210a1 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sun, 15 Feb 2009 23:38:53 -0800 Subject: s3: Modify SMB_VFS_FILE_ID_CREATE to take a stat struct Since file_id_create_dev is incompatible with the concept of file_ids, it is now static and in the one file that needs it. --- examples/VFS/skel_opaque.c | 2 +- examples/VFS/skel_transparent.c | 4 ++-- source3/include/proto.h | 1 - source3/include/vfs.h | 3 ++- source3/include/vfs_macros.h | 6 +++--- source3/lib/file_id.c | 17 +---------------- source3/modules/vfs_default.c | 14 ++++++++++++-- source3/modules/vfs_fileid.c | 6 +++--- source3/modules/vfs_full_audit.c | 6 +++--- source3/modules/vfs_streams_depot.c | 3 +-- source3/modules/vfs_xattr_tdb.c | 20 ++++++++++---------- source3/smbd/oplock_irix.c | 18 ++++++++++++++++++ 12 files changed, 56 insertions(+), 44 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 2eb7a94776..5845f62e34 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -292,7 +292,7 @@ static int skel_chflags(vfs_handle_struct *handle, const char *path, uint flags } static struct file_id skel_file_id_create(vfs_handle_struct *handle, - SMB_DEV_T dev, SMB_INO_T inode) + const SMB_STRUCT_STAT *sbuf) { struct file_id id_zero; ZERO_STRUCT(id_zero); diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 5670965417..7036c730dd 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -284,9 +284,9 @@ static int skel_chflags(vfs_handle_struct *handle, const char *path, uint flags } static struct file_id skel_file_id_create(vfs_handle_struct *handle, - SMB_DEV_T dev, SMB_INO_T inode) + const SMB_STRUCT_STAT *sbuf) { - return SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode); + return SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf); } static NTSTATUS skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, diff --git a/source3/include/proto.h b/source3/include/proto.h index 3806c9657e..bd44e9fdf4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -508,7 +508,6 @@ void dump_core_setup(const char *progname); /* The following definitions come from lib/file_id.c */ -struct file_id file_id_create_dev(SMB_DEV_T dev, SMB_INO_T inode); struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf); bool file_id_equal(const struct file_id *id1, const struct file_id *id2); const char *file_id_string_tos(const struct file_id *id); diff --git a/source3/include/vfs.h b/source3/include/vfs.h index ffa1a95ed0..0ee7f236b0 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -383,7 +383,8 @@ struct vfs_ops { struct notify_event *ev), void *private_data, void *handle_p); int (*chflags)(struct vfs_handle_struct *handle, const char *path, unsigned int flags); - struct file_id (*file_id_create)(struct vfs_handle_struct *handle, SMB_DEV_T dev, SMB_INO_T inode); + struct file_id (*file_id_create)(struct vfs_handle_struct *handle, + const SMB_STRUCT_STAT *sbuf); NTSTATUS (*streaminfo)(struct vfs_handle_struct *handle, struct files_struct *fsp, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 3af612375b..7dacd2319a 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -85,7 +85,7 @@ #define SMB_VFS_REALPATH(conn, path, resolved_path) ((conn)->vfs.ops.realpath((conn)->vfs.handles.realpath, (path), (resolved_path))) #define SMB_VFS_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs.ops.notify_watch((conn)->vfs.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p))) #define SMB_VFS_CHFLAGS(conn, path, flags) ((conn)->vfs.ops.chflags((conn)->vfs.handles.chflags, (path), (flags))) -#define SMB_VFS_FILE_ID_CREATE(conn, dev, inode) ((conn)->vfs.ops.file_id_create((conn)->vfs.handles.file_id_create, (dev), (inode))) +#define SMB_VFS_FILE_ID_CREATE(conn, sbuf) ((conn)->vfs.ops.file_id_create((conn)->vfs.handles.file_id_create, (sbuf))) #define SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams) ((conn)->vfs.ops.streaminfo((conn)->vfs.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams))) #define SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) ((conn)->vfs.ops.get_real_filename((conn)->vfs.handles.get_real_filename, (path), (name), (mem_ctx), (found_name))) #define SMB_VFS_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs.ops.brl_lock_windows((conn)->vfs.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr))) @@ -217,7 +217,7 @@ #define SMB_VFS_OPAQUE_REALPATH(conn, path, resolved_path) ((conn)->vfs_opaque.ops.realpath((conn)->vfs_opaque.handles.realpath, (path), (resolved_path))) #define SMB_VFS_OPAQUE_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs_opaque.ops.notify_watch((conn)->vfs_opaque.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p))) #define SMB_VFS_OPAQUE_CHFLAGS(conn, path, flags) ((conn)->vfs_opaque.ops.chflags((conn)->vfs_opaque.handles.chflags, (path), (flags))) -#define SMB_VFS_OPAQUE_FILE_ID_CREATE(conn, dev, inode) ((conn)->vfs.ops_opaque.file_id_create((conn)->vfs_opaque.handles.file_id_create, (dev), (inode))) +#define SMB_VFS_OPAQUE_FILE_ID_CREATE(conn, sbuf) ((conn)->vfs.ops_opaque.file_id_create((conn)->vfs_opaque.handles.file_id_create, (sbuf))) #define SMB_VFS_OPAQUE_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams) ((conn)->vfs_opaque.ops.streaminfo((conn)->vfs_opaque.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams))) #define SMB_VFS_OPAQUE_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) ((conn)->vfs_opaque.ops.get_real_filename((conn)->vfs_opaque.handles.get_real_filename, (path), (name), (mem_ctx), (found_name))) #define SMB_VFS_OPAQUE_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs_opaque.ops.brl_lock_windows((conn)->vfs_opaque.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr))) @@ -350,7 +350,7 @@ #define SMB_VFS_NEXT_REALPATH(handle, path, resolved_path) ((handle)->vfs_next.ops.realpath((handle)->vfs_next.handles.realpath, (path), (resolved_path))) #define SMB_VFS_NEXT_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs_next.ops.notify_watch((conn)->vfs_next.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p))) #define SMB_VFS_NEXT_CHFLAGS(handle, path, flags) ((handle)->vfs_next.ops.chflags((handle)->vfs_next.handles.chflags, (path), (flags))) -#define SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode) ((handle)->vfs_next.ops.file_id_create((handle)->vfs_next.handles.file_id_create, (dev), (inode))) +#define SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf) ((handle)->vfs_next.ops.file_id_create((handle)->vfs_next.handles.file_id_create, (sbuf))) #define SMB_VFS_NEXT_STREAMINFO(handle, fsp, fname, mem_ctx, num_streams, streams) ((handle)->vfs_next.ops.streaminfo((handle)->vfs_next.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams))) #define SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx, found_name) ((handle)->vfs_next.ops.get_real_filename((handle)->vfs_next.handles.get_real_filename, (path), (name), (mem_ctx), (found_name))) #define SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock, blocking_lock, blr) ((handle)->vfs_next.ops.brl_lock_windows((handle)->vfs_next.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr))) diff --git a/source3/lib/file_id.c b/source3/lib/file_id.c index 0633d4b88d..355aafa344 100644 --- a/source3/lib/file_id.c +++ b/source3/lib/file_id.c @@ -21,27 +21,12 @@ #include "includes.h" -/* - return a file_id which gives a unique ID for a file given the device and - inode numbers - */ -struct file_id file_id_create_dev(SMB_DEV_T dev, SMB_INO_T inode) -{ - struct file_id key; - /* the ZERO_STRUCT ensures padding doesn't break using the key as a - * blob */ - ZERO_STRUCT(key); - key.devid = dev; - key.inode = inode; - return key; -} - /* generate a file_id from a stat structure */ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf) { - return SMB_VFS_FILE_ID_CREATE(conn, sbuf->st_dev, sbuf->st_ino); + return SMB_VFS_FILE_ID_CREATE(conn, sbuf); } /* diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index f52ca09c08..c18ec268d3 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1042,9 +1042,19 @@ static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flag #endif } -static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, SMB_DEV_T dev, SMB_INO_T inode) +static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, + SMB_STRUCT_STAT *sbuf) { - return file_id_create_dev(dev, inode); + struct file_id key; + + /* the ZERO_STRUCT ensures padding doesn't break using the key as a + * blob */ + ZERO_STRUCT(key); + + key.devid = sbuf->st_dev; + key.inode = sbuf->st_ino; + + return key; } static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_fileid.c b/source3/modules/vfs_fileid.c index 787a49f36b..8152c5477e 100644 --- a/source3/modules/vfs_fileid.c +++ b/source3/modules/vfs_fileid.c @@ -226,7 +226,7 @@ static void fileid_disconnect(struct vfs_handle_struct *handle) } static struct file_id fileid_file_id_create(struct vfs_handle_struct *handle, - SMB_DEV_T dev, SMB_INO_T inode) + const SMB_STRUCT_STAT *sbuf) { struct fileid_handle_data *data; struct file_id id; @@ -237,8 +237,8 @@ static struct file_id fileid_file_id_create(struct vfs_handle_struct *handle, struct fileid_handle_data, return id); - id.devid = data->device_mapping_fn(data, dev); - id.inode = inode; + id.devid = data->device_mapping_fn(data, sbuf->st_dev); + id.inode = sbuf->st_ino; return id; } diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 15eafc1b56..3c159f10eb 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -209,7 +209,7 @@ static NTSTATUS smb_full_audit_notify_watch(struct vfs_handle_struct *handle, static int smb_full_audit_chflags(vfs_handle_struct *handle, const char *path, unsigned int flags); static struct file_id smb_full_audit_file_id_create(struct vfs_handle_struct *handle, - SMB_DEV_T dev, SMB_INO_T inode); + const SMB_STRUCT_STAT *sbuf); static NTSTATUS smb_full_audit_streaminfo(vfs_handle_struct *handle, struct files_struct *fsp, const char *fname, @@ -1664,14 +1664,14 @@ static int smb_full_audit_chflags(vfs_handle_struct *handle, } static struct file_id smb_full_audit_file_id_create(struct vfs_handle_struct *handle, - SMB_DEV_T dev, SMB_INO_T inode) + const SMB_STRUCT_STAT *sbuf) { struct file_id id_zero; struct file_id result; ZERO_STRUCT(id_zero); - result = SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode); + result = SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf); do_log(SMB_VFS_OP_FILE_ID_CREATE, !file_id_equal(&id_zero, &result), diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index 1c2c0e5f77..9329be7a9c 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -153,8 +153,7 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path, base_sbuf = &sbuf; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, base_sbuf->st_dev, - base_sbuf->st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, base_sbuf); push_file_id_16((char *)id_buf, &id); diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 44bfffb94e..908a2a3872 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -216,7 +216,7 @@ static ssize_t xattr_tdb_getxattr(struct vfs_handle_struct *handle, return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); return xattr_tdb_getattr(db, &id, name, value, size); } @@ -235,7 +235,7 @@ static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle, return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); return xattr_tdb_getattr(db, &id, name, value, size); } @@ -338,7 +338,7 @@ static int xattr_tdb_setxattr(struct vfs_handle_struct *handle, return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); return xattr_tdb_setattr(db, &id, name, value, size, flags); } @@ -358,7 +358,7 @@ static int xattr_tdb_fsetxattr(struct vfs_handle_struct *handle, return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); return xattr_tdb_setattr(db, &id, name, value, size, flags); } @@ -443,7 +443,7 @@ static ssize_t xattr_tdb_listxattr(struct vfs_handle_struct *handle, return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); return xattr_tdb_listattr(db, &id, list, size); } @@ -462,7 +462,7 @@ static ssize_t xattr_tdb_flistxattr(struct vfs_handle_struct *handle, return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); return xattr_tdb_listattr(db, &id, list, size); } @@ -543,7 +543,7 @@ static int xattr_tdb_removexattr(struct vfs_handle_struct *handle, return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); return xattr_tdb_removeattr(db, &id, name); } @@ -561,7 +561,7 @@ static int xattr_tdb_fremovexattr(struct vfs_handle_struct *handle, return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); return xattr_tdb_removeattr(db, &id, name); } @@ -628,7 +628,7 @@ static int xattr_tdb_unlink(vfs_handle_struct *handle, const char *path) return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id); @@ -667,7 +667,7 @@ static int xattr_tdb_rmdir(vfs_handle_struct *handle, const char *path) return -1; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id); diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c index bbc9132a08..89b8e0f7b5 100644 --- a/source3/smbd/oplock_irix.c +++ b/source3/smbd/oplock_irix.c @@ -103,6 +103,24 @@ static bool irix_oplocks_available(void) return True; } +/* + * This is bad because the file_id should always be created through the vfs + * layer! Unfortunately, a conn struct isn't available here. + */ +static struct file_id file_id_create_dev(SMB_DEV_T dev, SMB_INO_T inode) +{ + struct file_id key; + + /* the ZERO_STRUCT ensures padding doesn't break using the key as a + * blob */ + ZERO_STRUCT(key); + + key.devid = dev; + key.inode = inode; + + return key; +} + /**************************************************************************** * Deal with the IRIX kernel <--> smbd * oplock break protocol. -- cgit From e4675ce8db436ac572fcc476b9bfb1116e997f9f Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sun, 15 Feb 2009 23:45:28 -0800 Subject: s3: Add extid to the dev/inode pair This extends the file_id struct to add an additional generic uint64_t field: extid. For backwards compatibility with dev/inodes stored in xattr_tdbs and acl_tdbs, the ext id is ignored for these databases. This patch should cause no functional change on systems that don't use SMB_VFS_FILE_ID_CREATE to set the extid. Existing code that uses the smb_share_mode library will need to be updated to be compatibile with the new extid. --- source3/include/locking.h | 1 + source3/include/proto.h | 3 ++- source3/include/smb.h | 48 +++++++++++++++++++++------------------ source3/include/smb_share_modes.h | 11 +++++++-- source3/lib/file_id.c | 30 +++++++++++++++++++----- source3/libsmb/smb_share_modes.c | 39 +++++++++++++++++++++---------- source3/locking/locking.c | 6 ++--- source3/modules/vfs_acl_tdb.c | 6 +++++ source3/modules/vfs_default.c | 1 + source3/modules/vfs_xattr_tdb.c | 3 +++ source3/smbd/globals.c | 3 ++- source3/smbd/nttrans.c | 2 ++ source3/smbd/open.c | 4 ++-- source3/smbd/oplock.c | 28 +++++++++++------------ 14 files changed, 122 insertions(+), 63 deletions(-) diff --git a/source3/include/locking.h b/source3/include/locking.h index 3fd5b94de7..1833ba3f80 100644 --- a/source3/include/locking.h +++ b/source3/include/locking.h @@ -49,6 +49,7 @@ struct file_id { other than a dev_t for the device */ uint64_t devid; uint64_t inode; + uint64_t extid; /* Support systems that use an extended id (e.g. snapshots). */ }; struct byte_range_lock { diff --git a/source3/include/proto.h b/source3/include/proto.h index bd44e9fdf4..ab1f2f4f4f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -512,7 +512,8 @@ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_S bool file_id_equal(const struct file_id *id1, const struct file_id *id2); const char *file_id_string_tos(const struct file_id *id); void push_file_id_16(char *buf, const struct file_id *id); -void pull_file_id_16(char *buf, struct file_id *id); +void push_file_id_24(char *buf, const struct file_id *id); +void pull_file_id_24(char *buf, struct file_id *id); /* The following definitions come from lib/gencache.c */ diff --git a/source3/include/smb.h b/source3/include/smb.h index bef0fd177b..ec5bb71798 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -758,18 +758,19 @@ Offset Data length. 16 uint32 private_options 4 20 uint32 time sec 4 24 uint32 time usec 4 -28 SMB_DEV_T dev 8 bytes. -36 SMB_INO_T inode 8 bytes -44 unsigned long file_id 4 bytes -48 uint32 uid 4 bytes -52 uint16 flags 2 bytes -54 +28 uint64 dev 8 bytes +36 uint64 inode 8 bytes +44 uint64 extid 8 bytes +52 unsigned long file_id 4 bytes +56 uint32 uid 4 bytes +60 uint16 flags 2 bytes +62 */ #ifdef CLUSTER_SUPPORT -#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 58 +#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 66 #else -#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 54 +#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 62 #endif struct share_mode_lock { @@ -1631,37 +1632,40 @@ struct inform_level2_message { /* kernel_oplock_message definition. struct kernel_oplock_message { - SMB_DEV_T dev; - SMB_INO_T inode; + uint64_t dev; + uint64_t inode; + unit64_t extid; unsigned long file_id; }; Offset Data length. -0 SMB_DEV_T dev 8 bytes. -8 SMB_INO_T inode 8 bytes -16 unsigned long file_id 4 bytes -20 +0 uint64_t dev 8 bytes +8 uint64_t inode 8 bytes +16 uint64_t extid 8 bytes +24 unsigned long file_id 4 bytes +28 */ -#define MSG_SMB_KERNEL_BREAK_SIZE 20 +#define MSG_SMB_KERNEL_BREAK_SIZE 28 /* file_renamed_message definition. struct file_renamed_message { - SMB_DEV_T dev; - SMB_INO_T inode; + uint64_t dev; + uint64_t inode; char names[1]; A variable area containing sharepath and filename. }; Offset Data length. -0 SMB_DEV_T dev 8 bytes. -8 SMB_INO_T inode 8 bytes -16 char [] name zero terminated namelen bytes -minimum length == 18. +0 uint64_t dev 8 bytes +8 uint64_t inode 8 bytes +16 unit64_t extid 8 bytes +24 char [] name zero terminated namelen bytes +minimum length == 24. */ -#define MSG_FILE_RENAMED_MIN_SIZE 16 +#define MSG_FILE_RENAMED_MIN_SIZE 24 /* * On the wire return values for oplock types. diff --git a/source3/include/smb_share_modes.h b/source3/include/smb_share_modes.h index 101bec8245..4a2d832cc2 100644 --- a/source3/include/smb_share_modes.h +++ b/source3/include/smb_share_modes.h @@ -46,6 +46,7 @@ struct smbdb_ctx; struct smb_share_mode_entry { uint64_t dev; uint64_t ino; + uint64_t extid; uint32_t share_access; uint32_t access_mask; struct timeval open_time; @@ -66,11 +67,13 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx); int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, - uint64_t ino); + uint64_t ino, + uint64_t extid); int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, - uint64_t ino); + uint64_t ino, + uint64_t extid); /* * Share mode database accessor functions. @@ -79,23 +82,27 @@ int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, struct smb_share_mode_entry **pp_list, unsigned char *p_delete_on_close); int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, const struct smb_share_mode_entry *set_entry, const char *path); int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, const struct smb_share_mode_entry *set_entry); int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, const struct smb_share_mode_entry *set_entry, const struct smb_share_mode_entry *new_entry); diff --git a/source3/lib/file_id.c b/source3/lib/file_id.c index 355aafa344..0902e3d224 100644 --- a/source3/lib/file_id.c +++ b/source3/lib/file_id.c @@ -34,7 +34,8 @@ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_S */ bool file_id_equal(const struct file_id *id1, const struct file_id *id2) { - return id1->inode == id2->inode && id1->devid == id2->devid; + return id1->inode == id2->inode && id1->devid == id2->devid && + id1->extid == id2->extid; } /* @@ -42,15 +43,17 @@ bool file_id_equal(const struct file_id *id1, const struct file_id *id2) */ const char *file_id_string_tos(const struct file_id *id) { - char *result = talloc_asprintf(talloc_tos(), "%llx:%llx", + char *result = talloc_asprintf(talloc_tos(), "%llx:%llx:%llx", (unsigned long long)id->devid, - (unsigned long long)id->inode); + (unsigned long long)id->inode, + (unsigned long long)id->extid); SMB_ASSERT(result != NULL); return result; } /* - push a 16 byte version of a file id into a buffer + push a 16 byte version of a file id into a buffer. This ignores the extid + and is needed when dev/inodes are stored in persistent storage (tdbs). */ void push_file_id_16(char *buf, const struct file_id *id) { @@ -61,13 +64,28 @@ void push_file_id_16(char *buf, const struct file_id *id) } /* - pul a 16 byte version of a file id from a buffer + push a 24 byte version of a file id into a buffer */ -void pull_file_id_16(char *buf, struct file_id *id) +void push_file_id_24(char *buf, const struct file_id *id) +{ + SIVAL(buf, 0, id->devid&0xFFFFFFFF); + SIVAL(buf, 4, id->devid>>32); + SIVAL(buf, 8, id->inode&0xFFFFFFFF); + SIVAL(buf, 12, id->inode>>32); + SIVAL(buf, 16, id->extid&0xFFFFFFFF); + SIVAL(buf, 20, id->extid>>32); +} + +/* + pull a 24 byte version of a file id from a buffer + */ +void pull_file_id_24(char *buf, struct file_id *id) { ZERO_STRUCTP(id); id->devid = IVAL(buf, 0); id->devid |= ((uint64_t)IVAL(buf,4))<<32; id->inode = IVAL(buf, 8); id->inode |= ((uint64_t)IVAL(buf,12))<<32; + id->extid = IVAL(buf, 16); + id->extid |= ((uint64_t)IVAL(buf,20))<<32; } diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index af3f7b0dd5..177e0114b3 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -38,7 +38,8 @@ struct smbdb_ctx { #endif int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev, - uint64_t ino, const struct smb_share_mode_entry *new_entry, + uint64_t ino, uint64_t extid, + const struct smb_share_mode_entry *new_entry, const char *sharepath, const char *filename); static bool sharemodes_procid_equal(const struct server_id *p1, const struct server_id *p2) @@ -83,6 +84,7 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path) struct locking_key { SMB_DEV_T dev; SMB_INO_T inode; + uint64_t extid; }; int smb_share_mode_db_close(struct smbdb_ctx *db_ctx) @@ -93,13 +95,14 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx) } static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev, - uint64_t ino) + uint64_t ino, uint64_t extid) { TDB_DATA ld; memset(lk, '\0', sizeof(*lk)); lk->dev = (SMB_DEV_T)dev; lk->inode = (SMB_INO_T)ino; + lk->extid = extid; ld.dptr = (uint8 *)lk; ld.dsize = sizeof(*lk); return ld; @@ -111,19 +114,22 @@ static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev, int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, - uint64_t ino) + uint64_t ino, + uint64_t extid) { struct locking_key lk; - return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino)); + return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino, + extid)); } int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, - uint64_t ino) + uint64_t ino, + uint64_t extid) { struct locking_key lk; return tdb_chainunlock(db_ctx->smb_tdb, - get_locking_key(&lk, dev, ino)); + get_locking_key(&lk, dev, ino, extid)); } /* @@ -140,7 +146,8 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, e_entry->share_access == (uint32_t)entry->share_access && e_entry->access_mask == (uint32_t)entry->access_mask && e_entry->dev == entry->id.devid && - e_entry->ino == entry->id.inode); + e_entry->ino == entry->id.inode && + e_entry->extid == entry->id.extid); } /* @@ -160,6 +167,7 @@ static void create_share_mode_entry(struct share_mode_entry *out, out->access_mask = in->access_mask; out->id.devid = in->dev; out->id.inode = in->ino; + out->id.extid = in->extid; out->uid = (uint32)geteuid(); out->flags = 0; } @@ -172,6 +180,7 @@ static void create_share_mode_entry(struct share_mode_entry *out, int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, struct smb_share_mode_entry **pp_list, unsigned char *p_delete_on_close) { @@ -187,7 +196,8 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, *pp_list = NULL; *p_delete_on_close = 0; - db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino)); + db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino, + extid)); if (!db_data.dptr) { return 0; } @@ -229,6 +239,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, /* Copy into the external list. */ sme->dev = share->id.devid; sme->ino = share->id.inode; + sme->extid = share->id.extid; sme->share_access = (uint32_t)share->share_access; sme->access_mask = (uint32_t)share->access_mask; sme->open_time.tv_sec = share->time.tv_sec; @@ -257,13 +268,14 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, const struct smb_share_mode_entry *new_entry, const char *sharepath, /* Must be absolute utf8 path. */ const char *filename) /* Must be relative utf8 path. */ { TDB_DATA db_data; struct locking_key lk; - TDB_DATA locking_key = get_locking_key(&lk, dev, ino); + TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid); int orig_num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ struct share_mode_entry *shares = NULL; @@ -360,24 +372,26 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, const struct smb_share_mode_entry *new_entry, const char *filename) /* Must be absolute utf8 path. */ { if (*filename != '/') { abort(); } - return smb_create_share_mode_entry_ex(db_ctx, dev, ino, new_entry, + return smb_create_share_mode_entry_ex(db_ctx, dev, ino, extid, new_entry, "/", &filename[1]); } int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, const struct smb_share_mode_entry *del_entry) { TDB_DATA db_data; struct locking_key lk; - TDB_DATA locking_key = get_locking_key(&lk, dev, ino); + TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid); int orig_num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ struct share_mode_entry *shares = NULL; @@ -475,12 +489,13 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, + uint64_t extid, const struct smb_share_mode_entry *set_entry, const struct smb_share_mode_entry *new_entry) { TDB_DATA db_data; struct locking_key lk; - TDB_DATA locking_key = get_locking_key(&lk, dev, ino); + TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid); int num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ struct share_mode_entry *shares = NULL; diff --git a/source3/locking/locking.c b/source3/locking/locking.c index cc0295e749..1737eab1c6 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -923,12 +923,12 @@ bool rename_share_filename(struct messaging_context *msg_ctx, return False; } - push_file_id_16(frm, &lck->id); + push_file_id_24(frm, &lck->id); DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len )); - safe_strcpy(&frm[16], lck->servicepath, sp_len); - safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len); + safe_strcpy(&frm[24], lck->servicepath, sp_len); + safe_strcpy(&frm[24 + sp_len + 1], lck->filename, fn_len); /* Send the messages. */ for (i=0; inum_share_modes; i++) { diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 57fe73c814..909de9d7c8 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -94,6 +94,8 @@ static struct db_record *acl_tdb_lock(TALLOC_CTX *mem_ctx, const struct file_id *id) { uint8 id_buf[16]; + + /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, id); return db->fetch_locked(db, mem_ctx, @@ -200,6 +202,7 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, } id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, &id); if (db->fetch(db, @@ -285,6 +288,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, } id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, &id); rec = db->fetch_locked(db, talloc_tos(), make_tdb_data(id_buf, @@ -325,6 +329,8 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, } id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + + /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, &id); rec = db->fetch_locked(db, talloc_tos(), diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index c18ec268d3..7384268dae 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1053,6 +1053,7 @@ static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, key.devid = sbuf->st_dev; key.inode = sbuf->st_ino; + /* key.extid is unused by default. */ return key; } diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 908a2a3872..4e37ed6477 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -100,6 +100,7 @@ static NTSTATUS xattr_tdb_load_attrs(TALLOC_CTX *mem_ctx, NTSTATUS status; TDB_DATA data; + /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, id); if (db_ctx->fetch(db_ctx, mem_ctx, @@ -122,6 +123,8 @@ static struct db_record *xattr_tdb_lock_attrs(TALLOC_CTX *mem_ctx, const struct file_id *id) { uint8 id_buf[16]; + + /* For backwards compatibility only store the dev/inode. */ push_file_id_16((char *)id_buf, id); return db_ctx->fetch_locked(db_ctx, mem_ctx, make_tdb_data(id_buf, sizeof(id_buf))); diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c index 3f8cb411e5..9e7d103562 100644 --- a/source3/smbd/globals.c +++ b/source3/smbd/globals.c @@ -66,7 +66,8 @@ struct fsp_singleton_cache fsp_fi_cache = { .fsp = NULL, .id = { .devid = 0, - .inode = 0 + .inode = 0, + .extid = 0 } }; unsigned long file_gen_counter = 0; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index ad2366efae..86a46505a2 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1856,6 +1856,8 @@ static void call_nt_transact_ioctl(connection_struct *conn, reply_nterror(req, NT_STATUS_NO_MEMORY); return; } + + /* For backwards compatibility only store the dev/inode. */ push_file_id_16(pdata, &fsp->file_id); memcpy(pdata+16,create_volume_objectid(conn,objid),16); push_file_id_16(pdata+32, &fsp->file_id); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 9971ffa679..239d4ff0c4 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2597,8 +2597,8 @@ void msg_file_was_renamed(struct messaging_context *msg, } /* Unpack the message. */ - pull_file_id_16(frm, &id); - sharepath = &frm[16]; + pull_file_id_24(frm, &id); + sharepath = &frm[24]; newname = sharepath + strlen(sharepath) + 1; sp_len = strlen(sharepath); diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index b39e5bf634..22870283fa 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -40,8 +40,8 @@ void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp) uint8_t msg[MSG_SMB_KERNEL_BREAK_SIZE]; /* Put the kernel break info into the message. */ - push_file_id_16((char *)msg, &fsp->file_id); - SIVAL(msg,16,fsp->fh->gen_id); + push_file_id_24((char *)msg, &fsp->file_id); + SIVAL(msg,24,fsp->fh->gen_id); /* Don't need to be root here as we're only ever sending to ourselves. */ @@ -583,8 +583,8 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx, } /* Pull the data from the message. */ - pull_file_id_16((char *)data->data, &id); - file_id = (unsigned long)IVAL(data->data, 16); + pull_file_id_24((char *)data->data, &id); + file_id = (unsigned long)IVAL(data->data, 24); DEBUG(10, ("Got kernel oplock break message from pid %d: %s/%u\n", (int)procid_to_pid(&src), file_id_string_tos(&id), @@ -865,12 +865,12 @@ void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e) SIVAL(msg,16,e->private_options); SIVAL(msg,20,(uint32)e->time.tv_sec); SIVAL(msg,24,(uint32)e->time.tv_usec); - push_file_id_16(msg+28, &e->id); - SIVAL(msg,44,e->share_file_id); - SIVAL(msg,48,e->uid); - SSVAL(msg,52,e->flags); + push_file_id_24(msg+28, &e->id); + SIVAL(msg,52,e->share_file_id); + SIVAL(msg,56,e->uid); + SSVAL(msg,60,e->flags); #ifdef CLUSTER_SUPPORT - SIVAL(msg,54,e->pid.vnn); + SIVAL(msg,62,e->pid.vnn); #endif } @@ -888,12 +888,12 @@ void message_to_share_mode_entry(struct share_mode_entry *e, char *msg) e->private_options = IVAL(msg,16); e->time.tv_sec = (time_t)IVAL(msg,20); e->time.tv_usec = (int)IVAL(msg,24); - pull_file_id_16(msg+28, &e->id); - e->share_file_id = (unsigned long)IVAL(msg,44); - e->uid = (uint32)IVAL(msg,48); - e->flags = (uint16)SVAL(msg,52); + pull_file_id_24(msg+28, &e->id); + e->share_file_id = (unsigned long)IVAL(msg,52); + e->uid = (uint32)IVAL(msg,56); + e->flags = (uint16)SVAL(msg,60); #ifdef CLUSTER_SUPPORT - e->pid.vnn = IVAL(msg,54); + e->pid.vnn = IVAL(msg,62); #endif } -- cgit From 2b53b791938bf6b6855b854561dcff70dbc328d3 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 16 Feb 2009 14:55:52 -0800 Subject: s3: Remove unused inform_level2_message struct --- source3/include/smb.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index ec5bb71798..f02088731d 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1621,14 +1621,6 @@ enum acl_compatibility {ACL_COMPAT_AUTO, ACL_COMPAT_WINNT, ACL_COMPAT_WIN2K}; #define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK) #define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)LEVEL_II_OPLOCK|(unsigned int)FAKE_LEVEL_II_OPLOCK)) -struct inform_level2_message { - SMB_DEV_T dev; - SMB_INO_T inode; - uint16 mid; - unsigned long target_file_id; - unsigned long source_file_id; -}; - /* kernel_oplock_message definition. struct kernel_oplock_message { -- cgit From 04a7213eb6a2b776c17a5b56ba3b66e3c3444507 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 16 Feb 2009 16:06:45 -0800 Subject: s3: Change the vfs_GetWd cache to use the file_id struct --- source3/smbd/vfs.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 9580247368..426772889c 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -766,18 +766,13 @@ int vfs_ChDir(connection_struct *conn, const char *path) format. Note this can be called with conn == NULL. ********************************************************************/ -struct getwd_cache_key { - SMB_DEV_T dev; - SMB_INO_T ino; -}; - char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn) { char s[PATH_MAX+1]; SMB_STRUCT_STAT st, st2; char *result; DATA_BLOB cache_value; - struct getwd_cache_key key; + struct file_id key; *s = 0; @@ -797,9 +792,7 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn) goto nocache; } - ZERO_STRUCT(key); /* unlikely, but possible padding */ - key.dev = st.st_dev; - key.ino = st.st_ino; + key = vfs_file_id_from_sbuf(conn, &st); if (!memcache_lookup(smbd_memcache(), GETWD_CACHE, data_blob_const(&key, sizeof(key)), @@ -838,9 +831,7 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn) } if (lp_getwd_cache() && VALID_STAT(st)) { - ZERO_STRUCT(key); /* unlikely, but possible padding */ - key.dev = st.st_dev; - key.ino = st.st_ino; + key = vfs_file_id_from_sbuf(conn, &st); memcache_add(smbd_memcache(), GETWD_CACHE, data_blob_const(&key, sizeof(key)), -- cgit From 53bcd162ee4fd55fc5cc3293596f8733ce636b11 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 17 Feb 2009 18:38:58 -0800 Subject: s3 OneFS: Add file_id_create implementation to take advantage of snapshots --- source3/modules/vfs_onefs.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index 9667d86dba..522b94399d 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -194,6 +194,22 @@ static uint64_t onefs_get_alloc_size(struct vfs_handle_struct *handle, return result; } +static struct file_id onefs_file_id_create(struct vfs_handle_struct *handle, + SMB_STRUCT_STAT *sbuf) +{ + struct file_id key; + + /* the ZERO_STRUCT ensures padding doesn't break using the key as a + * blob */ + ZERO_STRUCT(key); + + key.devid = sbuf->st_dev; + key.inode = sbuf->st_ino; + key.extid = sbuf->st_snapid; + + return key; +} + static int onefs_statvfs(vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf) { @@ -342,6 +358,8 @@ static vfs_op_tuple onefs_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_chflags), SMB_VFS_OP_CHFLAGS, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_file_id_create), SMB_VFS_OP_FILE_ID_CREATE, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_streaminfo), SMB_VFS_OP_STREAMINFO, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_brl_lock_windows), SMB_VFS_OP_BRL_LOCK_WINDOWS, -- cgit From 73d5f14c04f2487f67695ce2e9ff025e25b2b026 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 17 Feb 2009 20:39:03 -0800 Subject: s3 OneFS: Add shadow copy module --- source3/Makefile.in | 5 + source3/configure.in | 3 +- source3/modules/onefs_shadow_copy.c | 782 ++++++++++++++++++++++++++++++++ source3/modules/onefs_shadow_copy.h | 32 ++ source3/modules/vfs_onefs_shadow_copy.c | 717 +++++++++++++++++++++++++++++ 5 files changed, 1538 insertions(+), 1 deletion(-) create mode 100644 source3/modules/onefs_shadow_copy.c create mode 100644 source3/modules/onefs_shadow_copy.h create mode 100644 source3/modules/vfs_onefs_shadow_copy.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 9bac7191fa..6ff90fc815 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -667,6 +667,7 @@ VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \ modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.c \ modules/onefs_cbrl.o +VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow_copy.o PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o PERFCOUNT_TEST_OBJ = modules/perfcount_test.o @@ -2559,6 +2560,10 @@ bin/onefs.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ONEFS_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_ONEFS_OBJ) @ONEFS_LIBS@ +bin/onefs_shadow_copy.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ONEFS_SHADOW_COPY_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_ONEFS_SHADOW_COPY_OBJ) + bin/pc_onefs.@SHLIBEXT@: $(BINARY_PREREQS) $(PERFCOUNT_ONEFS_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(PERFCOUNT_ONEFS_OBJ) diff --git a/source3/configure.in b/source3/configure.in index 57d475fcc5..b163a9dbb8 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1084,7 +1084,7 @@ AC_TRY_LINK([#include ], echo $samba_cv_HAVE_ONEFS if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS]) - default_shared_modules="$default_shared_modules vfs_onefs perfcount_onefs" + default_shared_modules="$default_shared_modules vfs_onefs vfs_onefs_shadow_copy perfcount_onefs" ONEFS_LIBS="-lisi_acl -lisi_ecs -lisi_event -lisi_util" # Need to also add general libs for oplocks support save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat" @@ -6178,6 +6178,7 @@ SMB_MODULE(vfs_acl_xattr, \$(VFS_ACL_XATTR_OBJ), "bin/acl_xattr.$SHLIBEXT", VFS) SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS) SMB_MODULE(vfs_smb_traffic_analyzer, \$(VFS_SMB_TRAFFIC_ANALYZER_OBJ), "bin/smb_traffic_analyzer.$SHLIBEXT", VFS) SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS) +SMB_MODULE(vfs_onefs_shadow_copy, \$(VFS_ONEFS_SHADOW_COPY), "bin/onefs_shadow_copy.$SHLIBEXT", VFS) SMB_SUBSYSTEM(VFS,smbd/vfs.o) diff --git a/source3/modules/onefs_shadow_copy.c b/source3/modules/onefs_shadow_copy.c new file mode 100644 index 0000000000..5b02534715 --- /dev/null +++ b/source3/modules/onefs_shadow_copy.c @@ -0,0 +1,782 @@ +/* + * Unix SMB/CIFS implementation. + * + * OneFS shadow copy implementation that utilizes the file system's native + * snapshot support. This file does all of the heavy lifting. + * + * Copyright (C) Dave Richards, 2007 + * Copyright (C) Tim Prouty, 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "onefs_shadow_copy.h" + +/* Copied from ../include/proto.h */ +void become_root(void); +void unbecome_root(void); + +#define SNAPSHOT_DIRECTORY ".snapshot" + +#define MAX_VERSIONS 64 + +/** + * A snapshot object. + * + * During snapshot enumeration, snapshots are represented by snapshot objects + * and are stored in a snapshot set. The snapshot object represents one + * snapshot within the set. An important thing to note about the set is that + * the key of the snapshot object is the tv_sec component of the is_time + * member. What this means is that we only store one snapshot for each + * second. If multiple snapshots were created within the same second, we'll + * keep the earliest one and ignore the rest. Thus, not all snapshots are + * necessarily retained. + */ +struct osc_snapshot { + char * is_name; + struct timespec is_time; + struct osc_snapshot * is_next; +}; + +/** + * A snapshot context object. + * + * Snapshot contexts are used to pass information throughout the snapshot + * enumeration routines. As a result, snapshot contexts are stored on the + * stack and are both created and destroyed within a single API function. + */ +struct osc_snapshot_ctx { + void * osc_set; + struct timespec osc_mtime; +}; + +/** + * A directory context. + * + * Directory contexts are the underlying data structured used to enumerate + * snapshot versions. An opendir()-, readdir()- and closedir()-like interface + * is provided that utilizes directory contexts. At the API level, directory + * contexts are passed around as void pointers. Directory contexts are + * allocated on the heap and their lifetime is dictated by the calling + * routine. + */ +struct osc_directory_ctx { + size_t idc_pos; + size_t idc_len; + size_t idc_size; + char ** idc_version; +}; + +/** + * Return a file descriptor to the STF names directory. + * + * Opens the STF names directory and returns a file descriptor to it. + * Subsequent calls return the same value (avoiding the need to re-open the + * directory repeatedly). Caveat caller: don't close the file descriptor or + * you will be shot! + */ +static int +osc_get_names_directory_fd(void) +{ + static int fd = -1; + + if (fd == -1) { + become_root(); + fd = pctl2_lin_open(STF_NAMES_LIN, HEAD_SNAPID, O_RDONLY); + unbecome_root(); + } + + return fd; +} + +/** + * Compare two time values. + * + * Accepts two struct timespecs and compares the tv_sec components of these + * values. It returns -1 if the first value preceeds the second, 0 if they + * are equal and +1 if the first values succeeds the second. + */ +static int +osc_time_compare(const struct timespec *tsp1, const struct timespec *tsp2) +{ + return (tsp1->tv_sec < tsp2->tv_sec) ? -1 : + (tsp1->tv_sec > tsp2->tv_sec) ? +1 : 0; +} + +/** + * Compare two timespec values. + * + * Compares two timespec values. It returns -1 if the first value preceeds + * the second, 0 if they are equal and +1 if the first values succeeds the + * second. + */ +static int +osc_timespec_compare(const struct timespec *tsp1, const struct timespec *tsp2) +{ + return (tsp1->tv_sec < tsp2->tv_sec) ? -1 : + (tsp1->tv_sec > tsp2->tv_sec) ? +1 : + (tsp1->tv_nsec < tsp2->tv_nsec) ? -1 : + (tsp1->tv_nsec > tsp2->tv_nsec) ? +1 : 0; +} + +/** + * Determine whether a timespec value is zero. + * + * Return 1 if the struct timespec provided is zero and 0 otherwise. + */ +static int +osc_timespec_is_zero(const struct timespec *tsp) +{ + return (tsp->tv_sec == 0) && + (tsp->tv_nsec == 0); +} + +/** + * Create a snapshot object. + * + * Allocates and initializes a new snapshot object. In addition to allocating + * space for the snapshot object itself, space is allocated for the snapshot + * name. Both the name and time are then copied to the new object. + */ +static struct osc_snapshot * +osc_snapshot_create(const char *name, const struct timespec *tsp) +{ + struct osc_snapshot *isp; + + isp = malloc(sizeof *isp); + if (isp == NULL) + goto out; + + isp->is_name = malloc(strlen(name) + 1); + if (isp->is_name == NULL) { + free(isp); + isp = NULL; + goto out; + } + + strcpy(isp->is_name, name); + isp->is_time = *tsp; + isp->is_next = NULL; + + out: + return isp; +} + +/** + * Destroy a snapshot object. + * + * Frees both the name and the snapshot object itself. Appropriate NULL + * checking is performed because counting on free to do so is immoral. + */ +static void +osc_snapshot_destroy(struct osc_snapshot *isp) +{ + if (isp != NULL) { + if (isp->is_name != NULL) + free(isp->is_name); + free(isp); + } +} + +/** + * Destroy all snapshots in the snapshot list. + * + * Calls osc_snapshot_destroy() on each snapshot in the list. + */ +static void +osc_snapshot_destroy_list(struct osc_snapshot *isp) +{ + struct osc_snapshot *tmp; + + while (isp != NULL) { + tmp = isp; + isp = isp->is_next; + osc_snapshot_destroy(tmp); + } +} + +/** + * Compare two snapshot objects. + * + * Compare two snapshot objects. It is really just a wrapper for + * osc_time_compare(), which compare the time value of the two snapshots. + * N.B. time value in this context refers only to the tv_sec component. + */ +static int +osc_snapshot_compare(const void *vp1, const void *vp2) +{ + const struct osc_snapshot *isp1 = vp1; + const struct osc_snapshot *isp2 = vp2; + + return -osc_time_compare(&isp1->is_time, &isp2->is_time); +} + +/** + * Insert a snapshot into the snapshot set. + * + * Inserts a new snapshot into the snapshot set. The key for snapshots is + * their creation time (it's actually the seconds portion of the creation + * time). If a duplicate snapshot is found in the set, the new snapshot is + * added to a linked list of snapshots for that second. + */ +static void +osc_snapshot_insert(struct osc_snapshot_ctx *oscp, const char *name, + const struct timespec *tsp, int *errorp) +{ + struct osc_snapshot *isp1; + struct osc_snapshot **ispp; + + isp1 = osc_snapshot_create(name, tsp); + if (isp1 == NULL) { + *errorp = 1; + return; + } + + ispp = tsearch(isp1, &oscp->osc_set, osc_snapshot_compare); + if (ispp != NULL) { + struct osc_snapshot *isp2 = *ispp; + + /* If this is the only snapshot for this second, we're done. */ + if (isp2 == isp1) + return; + + /* Collision: add the new snapshot to the list. */ + isp1->is_next = isp2->is_next; + isp2->is_next = isp1; + + } else + *errorp = 1; + +} + +/** + * Process the next snapshot. + * + * Called for (almost) every entry in a .snapshot directory, ("." and ".." are + * ignored in osc_process_snapshot_directory()). All other entries are passed + * to osc_process_snapshot(), however. These entries can fall into one of two + * categories: snapshot names and snapshot aliases. We only care about + * snapshot names (as aliases are just redundant entries). Once it verifies + * that name represents a valid snapshot name, it calls fstat() to get the + * creation time of the snapshot and then calls osc_snapshot_insert() to add + * this entry to the snapshot set. + */ +static void +osc_process_snapshot(struct osc_snapshot_ctx *oscp, const char *name, + int *errorp) +{ + int fd; + struct stf_stat stf_stat; + struct stat stbuf; + + fd = osc_get_names_directory_fd(); + if (fd == -1) + goto out; + + fd = enc_openat(fd, name, ENC_DEFAULT, O_RDONLY); + if (fd == -1) + goto out; + + memset(&stf_stat, 0, sizeof stf_stat); + if (ifs_snap_stat(fd, &stf_stat) == -1) + goto out; + + if (stf_stat.sf_type != SF_STF) + goto out; + + if (fstat(fd, &stbuf) == -1) + goto out; + + osc_snapshot_insert(oscp, name, &stbuf.st_birthtimespec, errorp); + + out: + if (fd != -1) + close(fd); +} + +/** + * Process a snapshot directory. + * + * Opens the snapshot directory and calls osc_process_snapshot() for each + * entry. (Well ok, "." and ".." are ignored.) The goal here is to add all + * snapshots in the directory to the snapshot set. + */ +static void +osc_process_snapshot_directory(struct osc_snapshot_ctx *oscp, int *errorp) +{ + int fd; + struct stat stbuf; + DIR *dirp; + struct dirent *dp; + + fd = osc_get_names_directory_fd(); + if (fd == -1) + goto out; + + if (fstat(fd, &stbuf) == -1) + goto out; + + dirp = opendir(SNAPSHOT_DIRECTORY); + if (dirp == NULL) + goto out; + + for (;;) { + dp = readdir(dirp); + if (dp == NULL) + break; + + if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + continue; + + osc_process_snapshot(oscp, dp->d_name, errorp); + if (*errorp) + break; + } + + closedir(dirp); + + if (!*errorp) + oscp->osc_mtime = stbuf.st_mtimespec; + + out: + return; +} + +/** + * Initialize a snapshot context object. + * + * Clears all members of the context object. + */ +static void +osc_snapshot_ctx_init(struct osc_snapshot_ctx *oscp) +{ + memset(oscp, 0, sizeof *oscp); +} + +/** + * Desoy a snapshot context object. + * + * Frees all snapshots associated with the snapshot context and then calls + * osc_snapshot_ctx_init() to re-initialize the context object. + */ +static void +osc_snapshot_ctx_clean(struct osc_snapshot_ctx *oscp) +{ + struct osc_snapshot *tmp; + + while (oscp->osc_set != NULL) { + tmp = *(void **)oscp->osc_set; + tdelete(tmp, &oscp->osc_set, osc_snapshot_compare); + osc_snapshot_destroy_list(tmp); + } + + osc_snapshot_ctx_init(oscp); +} + +/** + * Return the "global" snapshot context. + * + * We maintain a single open snapshot context. Return a pointer to it. + */ +static struct osc_snapshot_ctx * +osc_get_snapshot_ctx(void) +{ + static struct osc_snapshot_ctx osc = { 0, { 0, 0 } }; + + return &osc; +} + +/** + * Determine whether a snapshot context is still valid. + * + * "Valid" in this context means "reusable". We can re-use a previous + * snapshot context iff we successfully built a previous snapshot context + * and no snapshots have been created or deleted since we did so. + * A "names" directory exists within our snapshot + * implementation in which all snapshot names are entered. Each time a + * snapshot is created or deleted, an entry must be added or removed. + * When this happens the modification time on the "names" directory + * changes. Therefore, a snapshot context is valid iff the context + * pointer is non-NULL, the cached modification time is non-zero + * (zero means uninitialized), and the modification time of the "names" + * directory matches the cached value. + */ +static int +osc_snapshot_ctx_is_valid(struct osc_snapshot_ctx *oscp) +{ + int fd; + struct stat stbuf; + + if (oscp == NULL) + return 0; + + if (osc_timespec_is_zero(&oscp->osc_mtime)) + return 0; + + fd = osc_get_names_directory_fd(); + if (fd == -1) + return 0; + + if (fstat(fd, &stbuf) == -1) + return 0; + + if (osc_timespec_compare(&oscp->osc_mtime, &stbuf.st_mtimespec) != 0) + return 0; + + return 1; +} + +/** + * Create and initialize a directory context. + * + * Allocates a directory context from the heap and initializes it. + */ +static struct osc_directory_ctx * +osc_directory_ctx_create(void) +{ + struct osc_directory_ctx *idcp; + + idcp = malloc(sizeof *idcp); + if (idcp != NULL) + memset(idcp, 0, sizeof *idcp); + + return idcp; +} + +/** + * Destroy a directory context. + * + * Frees any versions associated with the directory context and then frees the + * context itself. + */ +static void +osc_directory_ctx_destroy(struct osc_directory_ctx *idcp) +{ + int i; + + if (idcp == NULL) + return; + + for (i = 0; i < idcp->idc_len; i++) + free(idcp->idc_version[i]); + + free(idcp); +} + +/** + * Expand the size of a directory context's version list. + * + * If osc_directory_ctx_append_version() detects that the version list is too + * small to accomodate a new version string, it called + * osc_directory_ctx_expand_version_list() to expand the version list. + */ +static void +osc_directory_ctx_expand_version_list(struct osc_snapshot_ctx *oscp, + struct osc_directory_ctx *idcp, int *errorp) +{ + size_t size; + char **cpp; + + size = idcp->idc_size * 2 ?: 1; + + cpp = realloc(idcp->idc_version, size * sizeof (char *)); + if (cpp == NULL) { + *errorp = 1; + return; + } + + idcp->idc_size = size; + idcp->idc_version = cpp; +} + +/** + * Append a new version to a directory context. + * + * Appends a snapshot version to the + * directory context's version list. + */ +static void +osc_directory_ctx_append_version(struct osc_snapshot_ctx *oscp, + struct osc_directory_ctx *idcp, const struct timespec *tsp, int *errorp) +{ + char *cp; + struct tm *tmp; + char text[64]; + + if (idcp->idc_len >= MAX_VERSIONS) + return; + + if (idcp->idc_len >= idcp->idc_size) { + osc_directory_ctx_expand_version_list(oscp, idcp, errorp); + if (*errorp) + return; + } + + tmp = gmtime(&tsp->tv_sec); + if (tmp == NULL) { + *errorp = 1; + return; + } + + snprintf(text, sizeof text, + "@GMT-%04u.%02u.%02u-%02u.%02u.%02u", + tmp->tm_year + 1900, + tmp->tm_mon + 1, + tmp->tm_mday, + tmp->tm_hour, + tmp->tm_min, + tmp->tm_sec); + + cp = malloc(strlen(text) + 1); + if (cp == NULL) { + *errorp = 1; + return; + } + + strcpy(cp, text); + + idcp->idc_version[idcp->idc_len++] = cp; +} + +/** + * Make a directory context from a snapshot context. + * + * Once a snapshot context has been completely filled-in, + * osc_make_directory_ctx() is used to build a directory context from it. The + * idea here is to create version for each snapshot in the snapshot set. + */ +static void +osc_make_directory_ctx(struct osc_snapshot_ctx *oscp, + struct osc_directory_ctx *idcp, int *errorp) +{ + static void + walk(const void *vp, VISIT v, int level) + { + const struct osc_snapshot *isp; + + if ((v != postorder && v != leaf) || *errorp) + return; + + isp = *(const struct osc_snapshot **)(u_long)vp; + + osc_directory_ctx_append_version(oscp, idcp, &isp->is_time, + errorp); + } + + twalk(oscp->osc_set, walk); +} + +/** + * Open a version directory. + * + * Opens a version directory. What this really means is that + * osc_version_opendir() returns a handle to a directory context, which can be + * used to retrieve version strings. + */ +void * +osc_version_opendir(void) +{ + int error = 0; + struct osc_directory_ctx *idcp; + struct osc_snapshot_ctx *oscp; + + idcp = osc_directory_ctx_create(); + if (idcp == NULL) + goto error_out; + + oscp = osc_get_snapshot_ctx(); + + if (!osc_snapshot_ctx_is_valid(oscp)) { + osc_snapshot_ctx_clean(oscp); + osc_process_snapshot_directory(oscp, &error); + if (error) + goto error_out; + } + + osc_make_directory_ctx(oscp, idcp, &error); + if (error) + goto error_out; + + goto out; + + error_out: + if (idcp != NULL) { + osc_directory_ctx_destroy(idcp); + idcp = NULL; + } + + out: + return (void *)idcp; +} + +/** + * Read the next version directory entry. + * + * Returns the name of the next version in the version directory, or NULL if + * we're at the end of the directory. What this really does is return the + * next version from the version list stored in the directory context. + */ +char * +osc_version_readdir(void *vp) +{ + struct osc_directory_ctx *idcp = vp; + + if (idcp == NULL) + return NULL; + + if (idcp->idc_pos >= idcp->idc_len) + return NULL; + + return idcp->idc_version[idcp->idc_pos++]; +} + +/** + * Close the version directory. + * + * Destroys the underlying directory context. + */ +void +osc_version_closedir(void *vp) +{ + struct osc_directory_ctx *idcp = vp; + + if (idcp != NULL) + osc_directory_ctx_destroy(idcp); +} + +/** + * Canonicalize a path. + * + * Converts paths of the form @GMT-.. to paths of the form ../.snapshot/.. + * It's not the prettiest routine I've ever written, but what the heck? + */ +char * +osc_canonicalize_path(const char *path, char *snap_component) +{ + int error = 0; + struct osc_snapshot_ctx *oscp; + struct tm tm; + int n; + struct osc_snapshot is; + struct osc_snapshot **ispp; + struct osc_snapshot *isp; + char *cpath = NULL; + char *cpath2 = NULL; + const char *snap_component_orig = snap_component; + struct stat sb; + + oscp = osc_get_snapshot_ctx(); + + if (!osc_snapshot_ctx_is_valid(oscp)) { + osc_snapshot_ctx_clean(oscp); + osc_process_snapshot_directory(oscp, &error); + if (error) + goto out; + } + + memset(&tm, 0, sizeof tm); + n = sscanf(snap_component, + "@GMT-%4u.%2u.%2u-%2u.%2u.%2u", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday, + &tm.tm_hour, + &tm.tm_min, + &tm.tm_sec); + if (n != 6) + goto out; + + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + is.is_name = NULL; + is.is_time.tv_sec = timegm(&tm); + is.is_time.tv_nsec = 0; + + ispp = tfind(&is, &oscp->osc_set, osc_snapshot_compare); + if (ispp == NULL) + goto out; + isp = *ispp; + + /* Determine the path after "@GMT-..." */ + while (*snap_component != '/' && *snap_component != '\0') + snap_component++; + + while (*snap_component == '/') + snap_component++; + + cpath = malloc(strlen(SNAPSHOT_DIRECTORY) + strlen(isp->is_name) + + strlen(path) + 3); + + if (cpath == NULL) + goto out; + + /* + * Use the first snapshot that has a successful stat for the requested + * path. + */ + while (true) { + + sprintf(cpath, "%s/%s", SNAPSHOT_DIRECTORY, isp->is_name); + + /* Append path before "@GMT-..." */ + if (snap_component_orig != path) { + strcat(cpath, "/"); + strncat(cpath, path, snap_component_orig - path); + } + + /* Append path after "@GMT-..." */ + if (*snap_component != '\0') { + strcat(cpath, "/"); + strcat(cpath, snap_component); + } + + /* If there is a valid snapshot for this file, we're done. */ + if (stat(cpath, &sb) == 0) + break; + + /* Try the next snapshot. If this was the last one, give up. */ + isp = isp->is_next; + if (isp == NULL) + break; + + /* If the realloc fails, give up. */ + cpath2 = realloc(cpath, strlen(SNAPSHOT_DIRECTORY) + + strlen(isp->is_name) + strlen(path) + 3); + if (cpath2 == NULL) + break; + cpath = cpath2; + } + + out: + return cpath; +} diff --git a/source3/modules/onefs_shadow_copy.h b/source3/modules/onefs_shadow_copy.h new file mode 100644 index 0000000000..6415a4be1a --- /dev/null +++ b/source3/modules/onefs_shadow_copy.h @@ -0,0 +1,32 @@ +/* + * Unix SMB/CIFS implementation. + * + * OneFS shadow copy implementation that utilizes the file system's native + * snapshot support. + * + * Copyright (C) Dave Richards, 2007 + * Copyright (C) Tim Prouty, 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef ONEFS_SHADOW_COPY_H +#define ONEFS_SHADOW_COPY_H + +void *osc_version_opendir(void); +char *osc_version_readdir(void *vp); +void osc_version_closedir(void *vp); +char *osc_canonicalize_path(const char *path, char *snap_component); + +#endif /* ONEFS_SHADOW_COPY_H */ diff --git a/source3/modules/vfs_onefs_shadow_copy.c b/source3/modules/vfs_onefs_shadow_copy.c new file mode 100644 index 0000000000..28bc0c5081 --- /dev/null +++ b/source3/modules/vfs_onefs_shadow_copy.c @@ -0,0 +1,717 @@ +/* + * OneFS shadow copy implementation that utilizes the file system's native + * snapshot support. This is based on the original shadow copy module from + * 2004. + * + * Copyright (C) Stefan Metzmacher 2003-2004 + * Copyright (C) Tim Prouty 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "onefs_shadow_copy.h" + +static int vfs_onefs_shadow_copy_debug_level = DBGC_VFS; + +#undef DBGC_CLASS +#define DBGC_CLASS vfs_onefs_shadow_copy_debug_level + +#define SHADOW_COPY_PREFIX "@GMT-" +#define SHADOW_COPY_SAMPLE "@GMT-2004.02.18-15.44.00" + +bool +shadow_copy_match_name(const char *name, char **snap_component) +{ + uint32 i = 0; + char delim[] = SHADOW_COPY_PREFIX; + char* start; + + start = strstr( name, delim ); + + /* + * The name could have SHADOW_COPY_PREFIX in it so we need to keep + * trying until we get something that is the full length of the + * SHADOW_COPY_SAMPLE. + */ + while (start != NULL) { + + DEBUG(10,("Processing %s\n", name)); + + /* size / correctness check */ + *snap_component = start; + for ( i = sizeof(SHADOW_COPY_PREFIX); + i < sizeof(SHADOW_COPY_SAMPLE); i++) { + if (start[i] == '/') { + if (i == sizeof(SHADOW_COPY_SAMPLE) - 1) + return true; + else + break; + } else if (start[i] == '\0') + return (i == sizeof(SHADOW_COPY_SAMPLE) - 1); + } + + start = strstr( start, delim ); + } + + return false; +} + +static int +onefs_shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, + files_struct *fsp, + SHADOW_COPY_DATA *shadow_copy_data, + bool labels) +{ + void *p = osc_version_opendir(); + char *snap_component = NULL; + shadow_copy_data->num_volumes = 0; + shadow_copy_data->labels = NULL; + + if (!p) { + DEBUG(0, ("shadow_copy_get_shadow_copy_data: osc_opendir() " + "failed for [%s]\n",fsp->conn->connectpath)); + return -1; + } + + while (true) { + SHADOW_COPY_LABEL *tlabels; + char *d; + + d = osc_version_readdir(p); + if (d == NULL) + break; + + if (!shadow_copy_match_name(d, &snap_component)) { + DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore " + "[%s]\n",d)); + continue; + } + + DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore " + "[%s]\n",d)); + + if (!labels) { + shadow_copy_data->num_volumes++; + continue; + } + + tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC( + shadow_copy_data->mem_ctx, + shadow_copy_data->labels, + (shadow_copy_data->num_volumes+1) * + sizeof(SHADOW_COPY_LABEL)); + + if (tlabels == NULL) { + DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of " + "memory\n")); + osc_version_closedir(p); + return -1; + } + + snprintf(tlabels[shadow_copy_data->num_volumes++], + sizeof(*tlabels), "%s",d); + + shadow_copy_data->labels = tlabels; + } + + osc_version_closedir(p); + + return 0; +} + +#define SHADOW_NEXT(op, args, rtype) do { \ + char *cpath = NULL; \ + char *snap_component = NULL; \ + rtype ret; \ + if (shadow_copy_match_name(path, &snap_component)) \ + cpath = osc_canonicalize_path(path, snap_component); \ + ret = SMB_VFS_NEXT_ ## op args; \ + SAFE_FREE(cpath); \ + return ret; \ + } while (0) \ + + + +static uint64_t +onefs_shadow_copy_disk_free(vfs_handle_struct *handle, const char *path, + bool small_query, uint64_t *bsize, uint64_t *dfree, + uint64_t *dsize) +{ + + SHADOW_NEXT(DISK_FREE, + (handle, cpath ?: path, small_query, bsize, dfree, dsize), + uint64_t); + +} + +static int +onefs_shadow_copy_statvfs(struct vfs_handle_struct *handle, const char *path, + struct vfs_statvfs_struct *statbuf) +{ + SHADOW_NEXT(STATVFS, + (handle, cpath ?: path, statbuf), + int); +} + +static SMB_STRUCT_DIR * +onefs_shadow_copy_opendir(vfs_handle_struct *handle, const char *path, + const char *mask, uint32_t attr) +{ + SHADOW_NEXT(OPENDIR, + (handle, cpath ?: path, mask, attr), + SMB_STRUCT_DIR *); +} + +static int +onefs_shadow_copy_mkdir(vfs_handle_struct *handle, const char *path, + mode_t mode) +{ + SHADOW_NEXT(MKDIR, + (handle, cpath ?: path, mode), + int); +} + +static int +onefs_shadow_copy_rmdir(vfs_handle_struct *handle, const char *path) +{ + SHADOW_NEXT(RMDIR, + (handle, cpath ?: path), + int); +} + +static int +onefs_shadow_copy_open(vfs_handle_struct *handle, const char *path, + files_struct *fsp, int flags, mode_t mode) +{ + SHADOW_NEXT(OPEN, + (handle, cpath ?: path, fsp, flags, mode), + int); +} + +static NTSTATUS +onefs_shadow_copy_create_file(vfs_handle_struct *handle, + struct smb_request *req, + uint16_t root_dir_fid, + const char *path, + uint32_t create_file_flags, + uint32_t access_mask, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options, + uint32_t file_attributes, + uint32_t oplock_request, + uint64_t allocation_size, + struct security_descriptor *sd, + struct ea_list *ea_list, + files_struct **result, + int *pinfo, + SMB_STRUCT_STAT *psbuf) +{ + SHADOW_NEXT(CREATE_FILE, + (handle, req, root_dir_fid, cpath ?: path, + create_file_flags, access_mask, share_access, + create_disposition, create_options, file_attributes, + oplock_request, allocation_size, sd, ea_list, result, + pinfo, psbuf), + NTSTATUS); +} + +/** + * XXX: macro-ize + */ +static int +onefs_shadow_copy_rename(vfs_handle_struct *handle, const char *old_name, + const char *new_name) +{ + char *old_cpath = NULL; + char *old_snap_component = NULL; + char *new_cpath = NULL; + char *new_snap_component = NULL; + int ret; + + if (shadow_copy_match_name(old_name, &old_snap_component)) + old_cpath = osc_canonicalize_path(old_name, old_snap_component); + + if (shadow_copy_match_name(new_name, &new_snap_component)) + new_cpath = osc_canonicalize_path(new_name, new_snap_component); + + ret = SMB_VFS_NEXT_RENAME(handle, old_cpath ?: old_name, + new_cpath ?: new_name); + + SAFE_FREE(old_cpath); + SAFE_FREE(new_cpath); + + return ret; +} + +static int +onefs_shadow_copy_stat(vfs_handle_struct *handle, const char *path, + SMB_STRUCT_STAT *sbuf) +{ + SHADOW_NEXT(STAT, + (handle, cpath ?: path, sbuf), + int); +} + +static int +onefs_shadow_copy_lstat(vfs_handle_struct *handle, const char *path, + SMB_STRUCT_STAT *sbuf) +{ + SHADOW_NEXT(LSTAT, + (handle, cpath ?: path, sbuf), + int); +} + +static int +onefs_shadow_copy_unlink(vfs_handle_struct *handle, const char *path) +{ + SHADOW_NEXT(UNLINK, + (handle, cpath ?: path), + int); +} + +static int +onefs_shadow_copy_chmod(vfs_handle_struct *handle, const char *path, + mode_t mode) +{ + SHADOW_NEXT(CHMOD, + (handle, cpath ?: path, mode), + int); +} + +static int +onefs_shadow_copy_chown(vfs_handle_struct *handle, const char *path, + uid_t uid, gid_t gid) +{ + SHADOW_NEXT(CHOWN, + (handle, cpath ?: path, uid, gid), + int); +} + +static int +onefs_shadow_copy_lchown(vfs_handle_struct *handle, const char *path, + uid_t uid, gid_t gid) +{ + SHADOW_NEXT(LCHOWN, + (handle, cpath ?: path, uid, gid), + int); +} + +static int +onefs_shadow_copy_chdir(vfs_handle_struct *handle, const char *path) +{ + SHADOW_NEXT(CHDIR, + (handle, cpath ?: path), + int); +} + +static int +onefs_shadow_copy_ntimes(vfs_handle_struct *handle, const char *path, + struct smb_file_time *ft) +{ + SHADOW_NEXT(NTIMES, + (handle, cpath ?: path, ft), + int); + +} + +/** + * XXX: macro-ize + */ +static bool +onefs_shadow_copy_symlink(vfs_handle_struct *handle, + const char *oldpath, const char *newpath) +{ + char *old_cpath = NULL; + char *old_snap_component = NULL; + char *new_cpath = NULL; + char *new_snap_component = NULL; + bool ret; + + if (shadow_copy_match_name(oldpath, &old_snap_component)) + old_cpath = osc_canonicalize_path(oldpath, old_snap_component); + + if (shadow_copy_match_name(newpath, &new_snap_component)) + new_cpath = osc_canonicalize_path(newpath, new_snap_component); + + ret = SMB_VFS_NEXT_SYMLINK(handle, old_cpath ?: oldpath, + new_cpath ?: newpath); + + SAFE_FREE(old_cpath); + SAFE_FREE(new_cpath); + + return ret; +} + +static bool +onefs_shadow_copy_readlink(vfs_handle_struct *handle, const char *path, + char *buf, size_t bufsiz) +{ + SHADOW_NEXT(READLINK, + (handle, cpath ?: path, buf, bufsiz), + bool); +} + +/** + * XXX: macro-ize + */ +static int +onefs_shadow_copy_link(vfs_handle_struct *handle, const char *oldpath, + const char *newpath) +{ + char *old_cpath = NULL; + char *old_snap_component = NULL; + char *new_cpath = NULL; + char *new_snap_component = NULL; + int ret; + + if (shadow_copy_match_name(oldpath, &old_snap_component)) + old_cpath = osc_canonicalize_path(oldpath, old_snap_component); + + if (shadow_copy_match_name(newpath, &new_snap_component)) + new_cpath = osc_canonicalize_path(newpath, new_snap_component); + + ret = SMB_VFS_NEXT_LINK(handle, old_cpath ?: oldpath, + new_cpath ?: newpath); + + SAFE_FREE(old_cpath); + SAFE_FREE(new_cpath); + + return ret; +} + +static int +onefs_shadow_copy_mknod(vfs_handle_struct *handle, const char *path, + mode_t mode, SMB_DEV_T dev) +{ + SHADOW_NEXT(MKNOD, + (handle, cpath ?: path, mode, dev), + int); +} + +static char * +onefs_shadow_copy_realpath(vfs_handle_struct *handle, const char *path, + char *resolved_path) +{ + SHADOW_NEXT(REALPATH, + (handle, cpath ?: path, resolved_path), + char *); +} + +static int onefs_shadow_copy_chflags(struct vfs_handle_struct *handle, + const char *path, unsigned int flags) +{ + SHADOW_NEXT(CHFLAGS, + (handle, cpath ?: path, flags), + int); +} + +static NTSTATUS +onefs_shadow_copy_streaminfo(struct vfs_handle_struct *handle, + struct files_struct *fsp, + const char *path, + TALLOC_CTX *mem_ctx, + unsigned int *num_streams, + struct stream_struct **streams) +{ + SHADOW_NEXT(STREAMINFO, + (handle, fsp, cpath ?: path, mem_ctx, num_streams, + streams), + NTSTATUS); +} + +static int +onefs_shadow_copy_get_real_filename(struct vfs_handle_struct *handle, + const char *full_path, + const char *path, + TALLOC_CTX *mem_ctx, + char **found_name) +{ + SHADOW_NEXT(GET_REAL_FILENAME, + (handle, full_path, cpath ?: path, mem_ctx, found_name), + int); +} + +static NTSTATUS +onefs_shadow_copy_get_nt_acl(struct vfs_handle_struct *handle, + const char *path, uint32 security_info, + struct security_descriptor **ppdesc) +{ + SHADOW_NEXT(GET_NT_ACL, + (handle, cpath ?: path, security_info, ppdesc), + NTSTATUS); +} + +static int +onefs_shadow_copy_chmod_acl(vfs_handle_struct *handle, const char *path, + mode_t mode) +{ + SHADOW_NEXT(CHMOD_ACL, + (handle, cpath ?: path, mode), + int); +} + +static SMB_ACL_T +onefs_shadow_copy_sys_acl_get_file(vfs_handle_struct *handle, + const char *path, SMB_ACL_TYPE_T type) +{ + SHADOW_NEXT(SYS_ACL_GET_FILE, + (handle, cpath ?: path, type), + SMB_ACL_T); +} + +static int +onefs_shadow_copy_sys_acl_set_file(vfs_handle_struct *handle, const char *path, + SMB_ACL_TYPE_T type, SMB_ACL_T theacl) +{ + SHADOW_NEXT(SYS_ACL_SET_FILE, + (handle, cpath ?: path, type, theacl), + int); +} + +static int +onefs_shadow_copy_sys_acl_delete_def_file(vfs_handle_struct *handle, + const char *path) +{ + SHADOW_NEXT(SYS_ACL_DELETE_DEF_FILE, + (handle, cpath ?: path), + int); +} + +static ssize_t +onefs_shadow_copy_getxattr(vfs_handle_struct *handle, const char *path, + const char *name, void *value, size_t size) +{ + SHADOW_NEXT(GETXATTR, + (handle, cpath ?: path, name, value, size), + ssize_t); +} + +static ssize_t +onefs_shadow_copy_lgetxattr(vfs_handle_struct *handle, const char *path, + const char *name, void *value, size_t size) +{ + SHADOW_NEXT(LGETXATTR, + (handle, cpath ?: path, name, value, size), + ssize_t); +} + +static ssize_t +onefs_shadow_copy_listxattr(vfs_handle_struct *handle, const char *path, + char *list, size_t size) +{ + SHADOW_NEXT(LISTXATTR, + (handle, cpath ?: path, list, size), + ssize_t); +} + +static ssize_t +onefs_shadow_copy_llistxattr(vfs_handle_struct *handle, const char *path, + char *list, size_t size) +{ + SHADOW_NEXT(LLISTXATTR, + (handle, cpath ?: path, list, size), + ssize_t); +} + +static int +onefs_shadow_copy_removexattr(vfs_handle_struct *handle, const char *path, + const char *name) +{ + SHADOW_NEXT(REMOVEXATTR, + (handle, cpath ?: path, name), + int); +} + +static int +onefs_shadow_copy_lremovexattr(vfs_handle_struct *handle, const char *path, + const char *name) +{ + SHADOW_NEXT(LREMOVEXATTR, + (handle, cpath ?: path, name), + int); +} + +static int +onefs_shadow_copy_setxattr(vfs_handle_struct *handle, const char *path, + const char *name, const void *value, size_t size, + int flags) +{ + SHADOW_NEXT(SETXATTR, + (handle, cpath ?: path, name, value, size, flags), + int); +} + +static int +onefs_shadow_copy_lsetxattr(vfs_handle_struct *handle, const char *path, + const char *name, const void *value, size_t size, + int flags) +{ + SHADOW_NEXT(LSETXATTR, + (handle, cpath ?: path, name, value, size, flags), + int); +} + +static bool +onefs_shadow_copy_is_offline(struct vfs_handle_struct *handle, + const char *path, SMB_STRUCT_STAT *sbuf) +{ + SHADOW_NEXT(IS_OFFLINE, + (handle, cpath ?: path, sbuf), + bool); +} + +static int +onefs_shadow_copy_set_offline(struct vfs_handle_struct *handle, + const char *path) +{ + SHADOW_NEXT(SET_OFFLINE, + (handle, cpath ?: path), + int); +} + +/* VFS operations structure */ + +static vfs_op_tuple onefs_shadow_copy_ops[] = { + + /* Disk operations */ + + {SMB_VFS_OP(onefs_shadow_copy_disk_free), SMB_VFS_OP_DISK_FREE, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_get_shadow_copy_data), + SMB_VFS_OP_GET_SHADOW_COPY_DATA, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(onefs_shadow_copy_statvfs), SMB_VFS_OP_STATVFS, + SMB_VFS_LAYER_TRANSPARENT}, + + /* Directory operations */ + + {SMB_VFS_OP(onefs_shadow_copy_opendir), SMB_VFS_OP_OPENDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_mkdir), SMB_VFS_OP_MKDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_rmdir), SMB_VFS_OP_RMDIR, + SMB_VFS_LAYER_TRANSPARENT}, + + /* File operations */ + + {SMB_VFS_OP(onefs_shadow_copy_open), SMB_VFS_OP_OPEN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_create_file), SMB_VFS_OP_CREATE_FILE, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_rename), SMB_VFS_OP_RENAME, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_stat), SMB_VFS_OP_STAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_stat), SMB_VFS_OP_STAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lstat), SMB_VFS_OP_LSTAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_unlink), SMB_VFS_OP_UNLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_chmod), SMB_VFS_OP_CHMOD, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_chown), SMB_VFS_OP_CHOWN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lchown), SMB_VFS_OP_LCHOWN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_chdir), SMB_VFS_OP_CHDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_ntimes), SMB_VFS_OP_NTIMES, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_symlink), SMB_VFS_OP_SYMLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_readlink), SMB_VFS_OP_READLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_link), SMB_VFS_OP_LINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_mknod), SMB_VFS_OP_MKNOD, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_realpath), SMB_VFS_OP_REALPATH, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_chflags), SMB_VFS_OP_CHFLAGS, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_streaminfo), SMB_VFS_OP_STREAMINFO, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_get_real_filename), + SMB_VFS_OP_GET_REAL_FILENAME, SMB_VFS_LAYER_TRANSPARENT}, + + /* NT File ACL operations */ + + {SMB_VFS_OP(onefs_shadow_copy_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT}, + + /* POSIX ACL operations */ + + {SMB_VFS_OP(onefs_shadow_copy_chmod_acl), SMB_VFS_OP_CHMOD_ACL, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_sys_acl_get_file), + SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_sys_acl_set_file), + SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_sys_acl_delete_def_file), + SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT}, + + /* EA operations. */ + + {SMB_VFS_OP(onefs_shadow_copy_getxattr), SMB_VFS_OP_GETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lgetxattr), SMB_VFS_OP_LGETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_listxattr), SMB_VFS_OP_LISTXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_llistxattr), SMB_VFS_OP_LLISTXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_removexattr), SMB_VFS_OP_REMOVEXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_setxattr), SMB_VFS_OP_SETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lsetxattr), SMB_VFS_OP_LSETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + + /* offline operations */ + {SMB_VFS_OP(onefs_shadow_copy_is_offline), SMB_VFS_OP_IS_OFFLINE, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_set_offline), SMB_VFS_OP_SET_OFFLINE, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_shadow_copy_init(void) +{ + NTSTATUS ret; + + ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, + "onefs_shadow_copy", + onefs_shadow_copy_ops); + + if (!NT_STATUS_IS_OK(ret)) + return ret; + + vfs_onefs_shadow_copy_debug_level = debug_add_class("onefs_shadow_copy"); + + if (vfs_onefs_shadow_copy_debug_level == -1) { + vfs_onefs_shadow_copy_debug_level = DBGC_VFS; + DEBUG(0, ("Couldn't register custom debugging class!\n")); + } else { + DEBUG(10, ("Debug class number of 'onefs_shadow_copy': %d\n", + vfs_onefs_shadow_copy_debug_level)); + } + + return ret; +} -- cgit From 54dbb030e2c6fed0abd0a3a89d08dad9b8a201a1 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 20 Feb 2009 09:20:16 +0100 Subject: s3/docs: Fix several typos. This fixes bug #6127. Thanks to Justin T Pryzby for the review! Karolin --- docs-xml/archives/THANKS | 2 +- docs-xml/smbdotconf/browse/enhancedbrowsing.xml | 2 +- docs-xml/smbdotconf/locking/strictlocking.xml | 2 +- docs-xml/smbdotconf/misc/remoteannounce.xml | 4 ++-- docs-xml/smbdotconf/misc/usershareallowguests.xml | 2 +- docs-xml/smbdotconf/misc/usershareprefixallowlist.xml | 4 ++-- docs-xml/smbdotconf/misc/usersharetemplateshare.xml | 2 +- docs-xml/smbdotconf/printing/useclientdriver.xml | 2 +- docs-xml/smbdotconf/protocol/aclcheckpermissions.xml | 2 +- docs-xml/smbdotconf/protocol/enableasusupport.xml | 2 +- docs-xml/smbdotconf/security/clientlanmanauth.xml | 2 +- docs-xml/smbdotconf/security/clientsigning.xml | 3 +-- docs-xml/smbdotconf/security/lanmanauth.xml | 2 +- docs-xml/smbdotconf/security/passwordserver.xml | 2 +- docs-xml/smbdotconf/security/security.xml | 6 +++--- docs-xml/smbdotconf/security/serverschannel.xml | 2 +- docs-xml/smbdotconf/security/serversigning.xml | 3 +-- docs-xml/smbdotconf/security/smbencrypt.xml | 3 +-- docs-xml/smbdotconf/security/updateencrypted.xml | 4 ++-- 19 files changed, 24 insertions(+), 27 deletions(-) diff --git a/docs-xml/archives/THANKS b/docs-xml/archives/THANKS index 789042f78e..37ecc99eeb 100644 --- a/docs-xml/archives/THANKS +++ b/docs-xml/archives/THANKS @@ -86,7 +86,7 @@ Tom Haapanen (tomh@metrics.com) consulting firm located in Waterloo, Ontario, Canada. We work with a variety of environments (such as Windows, Windows NT and Unix), tools and application areas, and can provide assistance for - development work ranging from a few days to to multiple man-year + development work ranging from a few days to multiple man-year projects. You can find more information at http://www.metrics.com/. diff --git a/docs-xml/smbdotconf/browse/enhancedbrowsing.xml b/docs-xml/smbdotconf/browse/enhancedbrowsing.xml index 13f2cd6446..7f85616c22 100644 --- a/docs-xml/smbdotconf/browse/enhancedbrowsing.xml +++ b/docs-xml/smbdotconf/browse/enhancedbrowsing.xml @@ -17,7 +17,7 @@ You may wish to disable this option if you have a problem with empty workgroups not disappearing from browse lists. Due to the restrictions - of the browse protocols these enhancements can cause a empty workgroup + of the browse protocols, these enhancements can cause a empty workgroup to stay around forever which can be annoying. In general you should leave this option enabled as it makes diff --git a/docs-xml/smbdotconf/locking/strictlocking.xml b/docs-xml/smbdotconf/locking/strictlocking.xml index e3a0ed7b4c..15ad0ad073 100644 --- a/docs-xml/smbdotconf/locking/strictlocking.xml +++ b/docs-xml/smbdotconf/locking/strictlocking.xml @@ -12,7 +12,7 @@ When strict locking is set to Auto (the default), the server performs file lock checks only on non-oplocked files. As most Windows redirectors perform file locking checks locally on oplocked files this is a good trade off for - inproved performance. + improved performance. diff --git a/docs-xml/smbdotconf/misc/remoteannounce.xml b/docs-xml/smbdotconf/misc/remoteannounce.xml index f23968b501..a6bf0c546f 100644 --- a/docs-xml/smbdotconf/misc/remoteannounce.xml +++ b/docs-xml/smbdotconf/misc/remoteannounce.xml @@ -6,7 +6,7 @@ This option allows you to setup nmbd - 8to periodically announce itself + 8 to periodically announce itself to arbitrary IP addresses with an arbitrary workgroup name. @@ -23,7 +23,7 @@ the above line would cause nmbd to announce itself to the two given IP addresses using the given workgroup names. If you leave out the - workgroup name then the one given in the parameter + workgroup name, then the one given in the parameter is used instead. diff --git a/docs-xml/smbdotconf/misc/usershareallowguests.xml b/docs-xml/smbdotconf/misc/usershareallowguests.xml index 738f3a11ba..a3ae5183b0 100644 --- a/docs-xml/smbdotconf/misc/usershareallowguests.xml +++ b/docs-xml/smbdotconf/misc/usershareallowguests.xml @@ -8,7 +8,7 @@ to be accessed by non-authenticated users or not. It is the equivalent of allowing people who can create a share the option of setting guest ok = yes in a share - definition. Due to the security sensitive nature of this the default + definition. Due to its security sensitive nature, the default is set to off. diff --git a/docs-xml/smbdotconf/misc/usershareprefixallowlist.xml b/docs-xml/smbdotconf/misc/usershareprefixallowlist.xml index bacc2e9530..6c1822a165 100644 --- a/docs-xml/smbdotconf/misc/usershareprefixallowlist.xml +++ b/docs-xml/smbdotconf/misc/usershareprefixallowlist.xml @@ -6,8 +6,8 @@ This parameter specifies a list of absolute pathnames the root of which are allowed to be exported by user defined share definitions. - If the pathname exported doesn't start with one of the strings in this - list the user defined share will not be allowed. This allows the Samba + If the pathname to be exported doesn't start with one of the strings in this + list, the user defined share will not be allowed. This allows the Samba administrator to restrict the directories on the system that can be exported by user defined shares. diff --git a/docs-xml/smbdotconf/misc/usersharetemplateshare.xml b/docs-xml/smbdotconf/misc/usersharetemplateshare.xml index efe2e81d22..9593a6c7e4 100644 --- a/docs-xml/smbdotconf/misc/usersharetemplateshare.xml +++ b/docs-xml/smbdotconf/misc/usersharetemplateshare.xml @@ -5,7 +5,7 @@ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> User defined shares only have limited possible parameters - such as path, guest ok etc. This parameter allows usershares to + such as path, guest ok, etc. This parameter allows usershares to "cloned" from an existing share. If "usershare template share" is set to the name of an existing share, then all usershares created have their defaults set from the parameters set on this diff --git a/docs-xml/smbdotconf/printing/useclientdriver.xml b/docs-xml/smbdotconf/printing/useclientdriver.xml index 99e8556811..4d9b7abfcc 100644 --- a/docs-xml/smbdotconf/printing/useclientdriver.xml +++ b/docs-xml/smbdotconf/printing/useclientdriver.xml @@ -29,7 +29,7 @@ If this parameter is enabled for a printer, then any attempt to open the printer with the PRINTER_ACCESS_ADMINISTER right is mapped to PRINTER_ACCESS_USE instead. Thus allowing the OpenPrinterEx() - call to succeed. This parameter MUST not be able enabled + call to succeed. This parameter MUST not be enabled on a print share which has valid print driver installed on the Samba server. diff --git a/docs-xml/smbdotconf/protocol/aclcheckpermissions.xml b/docs-xml/smbdotconf/protocol/aclcheckpermissions.xml index 6916261759..79b6da7afa 100644 --- a/docs-xml/smbdotconf/protocol/aclcheckpermissions.xml +++ b/docs-xml/smbdotconf/protocol/aclcheckpermissions.xml @@ -21,7 +21,7 @@ and allows the open. If the user doesn't have permission to delete the file this will only be discovered at close time, which is too late for the Windows user tools to display an error message to the user. The symptom of this is files that appear to have been deleted "magically" re-appearing - on a Windows explorer refersh. This is an extremely advanced protocol option which should not + on a Windows explorer refresh. This is an extremely advanced protocol option which should not need to be changed. This parameter was introduced in its final form in 3.0.21, an earlier version with slightly different semantics was introduced in 3.0.20. That older version is not documented here. diff --git a/docs-xml/smbdotconf/protocol/enableasusupport.xml b/docs-xml/smbdotconf/protocol/enableasusupport.xml index cd4f30fb8d..bb56b5ad0b 100644 --- a/docs-xml/smbdotconf/protocol/enableasusupport.xml +++ b/docs-xml/smbdotconf/protocol/enableasusupport.xml @@ -5,7 +5,7 @@ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> Hosts running the "Advanced Server for Unix (ASU)" product - require some special accomodations such as creating a builting [ADMIN$] + require some special accomodations such as creating a builtin [ADMIN$] share that only supports IPC connections. The has been the default behavior in smbd for many years. However, certain Microsoft applications such as the Print Migrator tool require that the remote server support diff --git a/docs-xml/smbdotconf/security/clientlanmanauth.xml b/docs-xml/smbdotconf/security/clientlanmanauth.xml index 5266fef6a2..967eacf85b 100644 --- a/docs-xml/smbdotconf/security/clientlanmanauth.xml +++ b/docs-xml/smbdotconf/security/clientlanmanauth.xml @@ -11,7 +11,7 @@ password hashes (e.g. Windows NT/2000, Samba, etc... but not Windows 95/98) will be able to be connected from the Samba client. - The LANMAN encrypted response is easily broken, due to it's + The LANMAN encrypted response is easily broken, due to its case-insensitive nature, and the choice of algorithm. Clients without Windows 95/98 servers are advised to disable this option. diff --git a/docs-xml/smbdotconf/security/clientsigning.xml b/docs-xml/smbdotconf/security/clientsigning.xml index bf37cbb874..c657e05711 100644 --- a/docs-xml/smbdotconf/security/clientsigning.xml +++ b/docs-xml/smbdotconf/security/clientsigning.xml @@ -4,8 +4,7 @@ basic="1" xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> - This controls whether the client offers or requires - the server it talks to to use SMB signing. Possible values + This controls whether the client is allowed or required to use SMB signing. Possible values are auto, mandatory and disabled. diff --git a/docs-xml/smbdotconf/security/lanmanauth.xml b/docs-xml/smbdotconf/security/lanmanauth.xml index 341952205f..4e68c5e03a 100644 --- a/docs-xml/smbdotconf/security/lanmanauth.xml +++ b/docs-xml/smbdotconf/security/lanmanauth.xml @@ -12,7 +12,7 @@ Windows 95/98 or the MS DOS network client) will be able to connect to the Samba host. - The LANMAN encrypted response is easily broken, due to it's + The LANMAN encrypted response is easily broken, due to its case-insensitive nature, and the choice of algorithm. Servers without Windows 95/98/ME or MS DOS clients are advised to disable this option. diff --git a/docs-xml/smbdotconf/security/passwordserver.xml b/docs-xml/smbdotconf/security/passwordserver.xml index 0da247d27d..0e92af9eba 100644 --- a/docs-xml/smbdotconf/security/passwordserver.xml +++ b/docs-xml/smbdotconf/security/passwordserver.xml @@ -7,7 +7,7 @@ By specifying the name of another SMB server or Active Directory domain controller with this option, and using security = [ads|domain|server] - it is possible to get Samba to + it is possible to get Samba to do all its username/password validation using a specific remote server. This option sets the name or IP address of the password server to use. diff --git a/docs-xml/smbdotconf/security/security.xml b/docs-xml/smbdotconf/security/security.xml index 3ad5175712..514ea54e0f 100644 --- a/docs-xml/smbdotconf/security/security.xml +++ b/docs-xml/smbdotconf/security/security.xml @@ -47,7 +47,7 @@ want to mainly setup shares without a password (guest shares). This is commonly used for a shared printer server. It is more difficult to setup guest shares with security = user, see - the parameter for details. + the parameter for details. It is possible to use smbd in a hybrid mode where it is offers both user and share @@ -58,7 +58,7 @@ SECURITY = SHARE - When clients connect to a share level security server they + When clients connect to a share level security server, they need not log onto the server with a valid username and password before attempting to connect to a shared resource (although modern clients such as Windows 95/98 and Windows NT will send a logon request with @@ -211,7 +211,7 @@ From the client's point of - view security = server is the + view, security = server is the same as security = user. It only affects how the server deals with the authentication, it does not in any way affect what the client sees. diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml index 6317448fb6..655463576f 100644 --- a/docs-xml/smbdotconf/security/serverschannel.xml +++ b/docs-xml/smbdotconf/security/serverschannel.xml @@ -13,7 +13,7 @@ - Please note that with this set to no you will have to apply the WindowsXP + Please note that with this set to no, you will have to apply the WindowsXP WinXP_SignOrSeal.reg registry patch found in the docs/registry subdirectory of the Samba distribution tarball. diff --git a/docs-xml/smbdotconf/security/serversigning.xml b/docs-xml/smbdotconf/security/serversigning.xml index f2f5629586..ea21a2c6f6 100644 --- a/docs-xml/smbdotconf/security/serversigning.xml +++ b/docs-xml/smbdotconf/security/serversigning.xml @@ -5,8 +5,7 @@ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> - This controls whether the server offers or requires - the client it talks to to use SMB signing. Possible values + This controls whether the client is allowed or required to use SMB signing. Possible values are auto, mandatory and disabled. diff --git a/docs-xml/smbdotconf/security/smbencrypt.xml b/docs-xml/smbdotconf/security/smbencrypt.xml index eb91ce51fa..d556166953 100644 --- a/docs-xml/smbdotconf/security/smbencrypt.xml +++ b/docs-xml/smbdotconf/security/smbencrypt.xml @@ -16,8 +16,7 @@ and MacOS/X clients. Windows clients do not support this feature. - This controls whether the server offers or requires - the client it talks to to use SMB encryption. Possible values + This controls whether the remote client is allowed or required to use SMB encryption. Possible values are auto, mandatory and disabled. This may be set on a per-share basis, but clients may chose to encrypt the entire session, not diff --git a/docs-xml/smbdotconf/security/updateencrypted.xml b/docs-xml/smbdotconf/security/updateencrypted.xml index da493665cf..eb54ed9bab 100644 --- a/docs-xml/smbdotconf/security/updateencrypted.xml +++ b/docs-xml/smbdotconf/security/updateencrypted.xml @@ -9,7 +9,7 @@ This boolean parameter allows a user logging on with a plaintext password to have their encrypted (hashed) password in the smbpasswd file to be updated automatically as they log on. This option allows a site to migrate from plaintext password authentication (users authenticate with plaintext password over the - wire, and are checked against a UNIX account atabase) to encrypted password authentication (the SMB + wire, and are checked against a UNIX account database) to encrypted password authentication (the SMB challenge/response authentication mechanism) without forcing all users to re-enter their passwords via smbpasswd at the time the change is made. This is a convenience option to allow the change over to encrypted passwords to be made over a longer period. Once all users have encrypted representations of their passwords @@ -24,7 +24,7 @@ - Note that even when this parameter is set a user authenticating to smbd + Note that even when this parameter is set, a user authenticating to smbd must still enter a valid password in order to connect correctly, and to update their hashed (smbpasswd) passwords. -- cgit From 3b0114c0ba676dec2ece96983aff29257399f378 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 20 Feb 2009 13:32:22 +0100 Subject: s3/docs: Add man vfs_acl_xattr. Karolin --- docs-xml/manpages-3/vfs_acl_xattr.8.xml | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docs-xml/manpages-3/vfs_acl_xattr.8.xml diff --git a/docs-xml/manpages-3/vfs_acl_xattr.8.xml b/docs-xml/manpages-3/vfs_acl_xattr.8.xml new file mode 100644 index 0000000000..b9377b297a --- /dev/null +++ b/docs-xml/manpages-3/vfs_acl_xattr.8.xml @@ -0,0 +1,61 @@ + + + + + + vfs_acl_xattr + 8 + Samba + System Administration tools + 3.3 + + + + + vfs_acl_xattr + Save NTFS-ACLs in Extended Attributes (EAs) + + + + + vfs objects = acl_xattr + + + + + DESCRIPTION + + This VFS module is part of the + samba + 7 suite. + + The vfs_acl_xattr VFS module stores + NTFS Access Control Lists (ACLs) in Extended Attributes (EAs). + This enables the full mapping of Windows ACLs on Samba + servers. + + + Please note that this module is + experimental! + + + This module is stackable. + + + + OPTIONS + + There are no options for vfs_acl_xattr. + + + + + AUTHOR + + The original Samba software and related utilities + were created by Andrew Tridgell. Samba is now developed + by the Samba Team as an Open Source project similar + to the way the Linux kernel is developed. + + + -- cgit From 0fd1d4c0906158bab55871d53396bdc7ae533220 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 20 Feb 2009 13:32:44 +0100 Subject: s3/docs: Add man vfs_acl_tdb. Karolin --- docs-xml/manpages-3/vfs_acl_tdb.8.xml | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 docs-xml/manpages-3/vfs_acl_tdb.8.xml diff --git a/docs-xml/manpages-3/vfs_acl_tdb.8.xml b/docs-xml/manpages-3/vfs_acl_tdb.8.xml new file mode 100644 index 0000000000..086b86f03e --- /dev/null +++ b/docs-xml/manpages-3/vfs_acl_tdb.8.xml @@ -0,0 +1,66 @@ + + + + + + vfs_acl_tdb + 8 + Samba + System Administration tools + 3.3 + + + + + vfs_acl_tdb + Save NTFS-ACLs in a tdb file + + + + + vfs objects = acl_tdb + + + + + DESCRIPTION + + This VFS module is part of the + samba + 7 suite. + + The vfs_acl_tdb VFS module stores + NTFS Access Control Lists (ACLs) in a tdb file. + This enables the full mapping of Windows ACLs on Samba + servers. + + + + The ACL settings are stored in + $LOCKDIR/file_ntacls.tdb. + + + Please note that this module is + experimental! + + + This module is stackable. + + + + OPTIONS + + There are no options for vfs_acl_tdb. + + + + + AUTHOR + + The original Samba software and related utilities + were created by Andrew Tridgell. Samba is now developed + by the Samba Team as an Open Source project similar + to the way the Linux kernel is developed. + + + -- cgit From 27307be0f726c899c0e8a0edfdf200650037bb61 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 20 Feb 2009 14:14:54 +0100 Subject: s3/docs: Add hint about getfattr in man vfs_acl_xattr. Karolin --- docs-xml/manpages-3/vfs_acl_xattr.8.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs-xml/manpages-3/vfs_acl_xattr.8.xml b/docs-xml/manpages-3/vfs_acl_xattr.8.xml index b9377b297a..7387824f79 100644 --- a/docs-xml/manpages-3/vfs_acl_xattr.8.xml +++ b/docs-xml/manpages-3/vfs_acl_xattr.8.xml @@ -35,6 +35,15 @@ servers. + The ACLs are stored in the Extended Attribute + security.NTACL of a file or directory. + This Attribute is not listed by + getfattr -d filename. + To show the current value, the name of the EA must be specified + (e.g. getfattr -n security.NTACL filename + ). + + Please note that this module is experimental! -- cgit From e256d72f0cd66c374f14a122623668de888aa5e7 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Fri, 20 Feb 2009 12:00:46 +0800 Subject: Make libsmbclient work with DFS Signed-off-by: Derrell Lipman --- source3/include/libsmbclient.h | 12 ++++++++++++ source3/libsmb/libsmb_context.c | 37 +++++++++++++++++++++++++++++++++++++ source3/libsmb/libsmb_dir.c | 27 +++++++++++++++++++++++++-- source3/libsmb/libsmb_file.c | 2 +- source3/libsmb/libsmb_path.c | 15 ++++++++++++++- source3/libsmb/libsmb_server.c | 19 ++++++++++++++++++- source3/libsmb/libsmb_stat.c | 2 +- 7 files changed, 108 insertions(+), 6 deletions(-) diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index f8a6c8a235..efc471c85b 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -2683,6 +2683,18 @@ smbc_set_credentials(char *workgroup, smbc_bool use_kerberos, char *signing_state); +/* + * Wrapper around smbc_set_credentials. + * Used to set correct credentials that will + * be used to connect to DFS target share + * in libsmbclient + */ + +void +smbc_set_credentials_with_fallback(SMBCCTX *ctx, + char *workgroup, + char *user, + char *password); /** * @ingroup structure diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index c1af48507c..0683f97ddd 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -652,3 +652,40 @@ smbc_set_credentials(char *workgroup, cli_cm_set_credentials(auth_info); TALLOC_FREE(auth_info); } + +void smbc_set_credentials_with_fallback(SMBCCTX *context, + char *workgroup, + char *user, + char *password) +{ + smbc_bool use_kerberos = false; + const char *signing_state = "off"; + + if (!context || !workgroup || !*workgroup + || !user || !*user || !password + || !*password) { + return; + } + + if (smbc_getOptionUseKerberos(context)) { + use_kerberos = True; + } + + if (lp_client_signing()) { + signing_state = "on"; + } + + if (lp_client_signing() == Required) { + signing_state = "force"; + } + + smbc_set_credentials(workgroup, + user, + password, + use_kerberos, + (char *)signing_state); + + if (smbc_getOptionFallbackAfterKerberos(context)) { + cli_cm_set_fallback_after_kerberos(); + } +} diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index e9b7b4f95a..1843fe262f 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -1500,6 +1500,8 @@ SMBC_chmod_ctx(SMBCCTX *context, char *user = NULL; char *password = NULL; char *workgroup = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; char *path = NULL; uint16 mode; TALLOC_CTX *frame = talloc_stackframe(); @@ -1550,6 +1552,14 @@ SMBC_chmod_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } + + /*d_printf(">>>unlink: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } mode = 0; @@ -1558,8 +1568,8 @@ SMBC_chmod_ctx(SMBCCTX *context, if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - if (!cli_setatr(srv->cli, path, mode, 0)) { - errno = SMBC_errno(context, srv->cli); + if (!cli_setatr(targetcli, targetpath, mode, 0)) { + errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; } @@ -1900,6 +1910,12 @@ SMBC_rename_ctx(SMBCCTX *ocontext, } + /* set the credentials to make DFS work */ + smbc_set_credentials_with_fallback(ocontext, + workgroup, + user1, + password1); + /*d_printf(">>>rename: resolving %s\n", path1);*/ if (!cli_resolve_path(frame, "", srv->cli, path1, &targetcli1, &targetpath1)) { @@ -1907,6 +1923,13 @@ SMBC_rename_ctx(SMBCCTX *ocontext, TALLOC_FREE(frame); return -1; } + + /* set the credentials to make DFS work */ + smbc_set_credentials_with_fallback(ncontext, + workgroup, + user2, + password2); + /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ /*d_printf(">>>rename: resolving %s\n", path2);*/ if (!cli_resolve_path(frame, "", srv->cli, path2, diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index ece056db87..28256bb241 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -382,7 +382,7 @@ SMBC_write_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>write: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index 6d69924231..3ea03446d8 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -233,6 +233,7 @@ SMBC_parse_path(TALLOC_CTX *ctx, char *s; const char *p; char *q, *r; + char *workgroup = NULL; int len; /* Ensure these returns are at least valid pointers. */ @@ -332,7 +333,6 @@ SMBC_parse_path(TALLOC_CTX *ctx, u = userinfo; if (strchr_m(u, ';')) { - char *workgroup; next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); if (!workgroup) { return -1; @@ -394,6 +394,19 @@ decoding: (void) urldecode_talloc(ctx, pp_share, *pp_share); (void) urldecode_talloc(ctx, pp_user, *pp_user); (void) urldecode_talloc(ctx, pp_password, *pp_password); + + if (!workgroup) { + workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context)); + } + if (!workgroup) { + return -1; + } + + /* set the credentials to make DFS work */ + smbc_set_credentials_with_fallback(context, + workgroup, + *pp_user, + *pp_password); return 0; } diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 6d7a86241a..eda37f2187 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -238,6 +238,7 @@ SMBC_server(TALLOC_CTX *ctx, char **pp_password) { SMBCSRV *srv=NULL; + char *workgroup = NULL; struct cli_state *c; struct nmb_name called, calling; const char *server_n = server; @@ -359,7 +360,7 @@ SMBC_server(TALLOC_CTX *ctx, if (srv) { /* ... then we're done here. Give 'em what they came for. */ - return srv; + goto done; } /* If we're not asked to connect when a connection doesn't exist... */ @@ -601,6 +602,22 @@ again: server, share, srv)); DLIST_ADD(context->internal->servers, srv); +done: + if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) { + workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context)); + } else { + workgroup = *pp_workgroup; + } + if(!workgroup) { + return NULL; + } + + /* set the credentials to make DFS work */ + smbc_set_credentials_with_fallback(context, + workgroup, + *pp_username, + *pp_password); + return srv; failed: diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 1ffe141796..f8571ff110 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -155,7 +155,7 @@ SMBC_stat_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { -- cgit From 45630c47fcc1ab96264d816313475af405079db3 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 20 Feb 2009 09:51:36 -0500 Subject: variable grouping: just my OCD desire to keep similar things together --- source3/libsmb/libsmb_context.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 0683f97ddd..e4df7fcb08 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -655,15 +655,17 @@ smbc_set_credentials(char *workgroup, void smbc_set_credentials_with_fallback(SMBCCTX *context, char *workgroup, - char *user, - char *password) + char *user, + char *password) { smbc_bool use_kerberos = false; const char *signing_state = "off"; - if (!context || !workgroup || !*workgroup - || !user || !*user || !password - || !*password) { + if (! context || + ! workgroup || ! *workgroup || + ! user || ! *user || + ! password || ! *password) { + return; } -- cgit From e6a5f11865a55e9644292ae92e4a4b5ec0662ccd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Feb 2009 08:23:52 -0800 Subject: Fix bug #6133 - Cannot delete non-ACL files on Solaris/ZFS/NFSv4 ACL filesystem. As the NFSv4 ACL mapping code doesn't map write directory into the DELETE_CHILD permission bit (which we require before allowing a delete) no one can delete files without an explicit DELETE_CHILD bit set on the directory. Add this mapping. Jeremy. --- source3/modules/nfs4_acls.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 556dad6b5e..ba038479af 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -198,6 +198,7 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf) static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */ DOM_SID *psid_owner, /* in */ DOM_SID *psid_group, /* in */ + bool is_directory, /* in */ SEC_ACE **ppnt_ace_list, /* out */ int *pgood_aces /* out */ ) @@ -256,6 +257,10 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */ DEBUG(10, ("mapped %d to %s\n", ace->who.id, sid_string_dbg(&sid))); + if (is_directory && (ace->aceMask & SMB_ACE4_ADD_FILE)) { + ace->aceMask |= SMB_ACE4_DELETE_CHILD; + } + mask = ace->aceMask; init_sec_ace(&nt_ace_list[good_aces++], &sid, ace->aceType, mask, @@ -287,7 +292,8 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, uid_to_sid(&sid_owner, sbuf->st_uid); gid_to_sid(&sid_group, sbuf->st_gid); - if (smbacl4_nfs42win(mem_ctx, acl, &sid_owner, &sid_group, &nt_ace_list, &good_aces)==False) { + if (smbacl4_nfs42win(mem_ctx, acl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_mode), + &nt_ace_list, &good_aces)==False) { DEBUG(8,("smbacl4_nfs42win failed\n")); return map_nt_error_from_unix(errno); } -- cgit From 1a0aed36c0fc3815c832be1086a3a66256426414 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Thu, 19 Feb 2009 17:06:27 -0800 Subject: Added torture tests to RAW-NOTIFY * This adds a test to check the change notify behavior of the SMB server when more events have been generated than can be returned in a single change notify response. * Second test makes sure the server doesn't return notification events for changes to the watched directory itself --- source4/torture/raw/notify.c | 152 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 2 deletions(-) diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c index 82f7d18323..3ffc58dbe6 100644 --- a/source4/torture/raw/notify.c +++ b/source4/torture/raw/notify.c @@ -561,7 +561,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t tv = timeval_current_ofs(1000, 0); t = timeval_to_nttime(&tv); - + /* get a handle on the directory */ @@ -1283,6 +1283,152 @@ done: return ret; } +/* + Test response when cached server events exceed single NT NOTFIY response + packet size. +*/ +static bool test_notify_overflow(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) +{ + bool ret = true; + NTSTATUS status; + union smb_notify notify; + union smb_open io; + int fnum, fnum2; + int count = 100; + struct smbcli_request *req1; + int i; + + printf("TESTING CHANGE NOTIFY EVENT OVERFLOW\n"); + + /* get a handle on the directory */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = SEC_FILE_ALL; + io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = BASEDIR; + + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + + /* ask for a change notify, on name changes. */ + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; + notify.nttrans.in.file.fnum = fnum; + + notify.nttrans.in.recursive = true; + req1 = smb_raw_changenotify_send(cli->tree, ¬ify); + + /* cancel initial requests so the buffer is setup */ + smb_raw_ntcancel(req1); + status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); + CHECK_STATUS(status, NT_STATUS_CANCELLED); + + /* open a lot of files, filling up the server side notify buffer */ + printf("testing overflowed buffer notify on create of %d files\n", + count); + for (i=0;itree, fname, O_CREAT|O_RDWR, + DENY_NONE); + if (fnum2 == -1) { + printf("Failed to create %s - %s\n", + fname, smbcli_errstr(cli->tree)); + ret = false; + goto done; + } + talloc_free(fname); + smbcli_close(cli->tree, fnum2); + } + + /* expect that 0 events will be returned with NT_STATUS_OK */ + req1 = smb_raw_changenotify_send(cli->tree, ¬ify); + status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(notify.nttrans.out.num_changes, 0); + +done: + smb_raw_exit(cli->session); + return ret; +} + +/* + Test if notifications are returned for changes to the base directory. + They shouldn't be. +*/ +static bool test_notify_basedir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) +{ + bool ret = true; + NTSTATUS status; + union smb_notify notify; + union smb_open io; + int fnum, fnum2; + int count = 100; + struct smbcli_request *req1; + int i; + + printf("TESTING CHANGE NOTIFY BASEDIR EVENTS\n"); + + /* get a handle on the directory */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = SEC_FILE_ALL; + io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = BASEDIR; + + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + + /* create a test file that will also be modified */ + smbcli_close(cli->tree, smbcli_open(cli->tree, BASEDIR "\\tname1", + O_CREAT, 0)); + + /* ask for a change notify, on attribute changes. */ + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_ATTRIBUTES; + notify.nttrans.in.file.fnum = fnum; + notify.nttrans.in.recursive = true; + + req1 = smb_raw_changenotify_send(cli->tree, ¬ify); + + /* set attribute on the base dir */ + smbcli_setatr(cli->tree, BASEDIR, FILE_ATTRIBUTE_HIDDEN, 0); + + /* set attribute on a file to assure we receive a notification */ + smbcli_setatr(cli->tree, BASEDIR "\\tname1", FILE_ATTRIBUTE_HIDDEN, 0); + msleep(200); + + /* check how many responses were given, expect only 1 for the file */ + status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_MODIFIED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "tname1", STR_UNICODE); + +done: + smb_raw_exit(cli->session); + return ret; +} + /* basic testing of change notify */ @@ -1291,7 +1437,7 @@ bool torture_raw_notify(struct torture_context *torture, struct smbcli_state *cli2) { bool ret = true; - + if (!torture_setup_dir(cli, BASEDIR)) { return false; } @@ -1307,6 +1453,8 @@ bool torture_raw_notify(struct torture_context *torture, ret &= test_notify_tcp_dis(torture); ret &= test_notify_double(cli, torture); ret &= test_notify_tree(cli, torture); + ret &= test_notify_overflow(cli, torture); + ret &= test_notify_basedir(cli, torture); smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); -- cgit From b329ea1cf35cfe151ac026eefc8ff82b2dfd711c Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 20 Feb 2009 13:23:53 -0800 Subject: s3: Modifications to generic notify structures to allow implementation of OneFS notify. The OneFS kernel based change notify system takes an fd of the directory to watch in it's initialization syscall. Since we already have this directory open, this commit plumbs that fd down to the VFS layer via the notify_entry struct. We also need to know if the watch is taken out on a snapshot directory. The full file_id struct is also passed down to make this determination. The file_id marshalling wrappers are hand written here, but should eventually be auto-generated by moving the struct file_id into the idl. --- source3/include/proto.h | 3 +++ source3/librpc/gen_ndr/ndr_notify.c | 8 ++++++++ source3/librpc/gen_ndr/notify.h | 2 ++ source3/librpc/idl/notify.idl | 2 ++ source3/librpc/ndr/util.c | 39 +++++++++++++++++++++++++++++++++++++ source3/smbd/notify.c | 2 ++ 6 files changed, 56 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index ab1f2f4f4f..1ac2ac23fb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2283,6 +2283,9 @@ ADS_STATUS gp_get_machine_token(ADS_STRUCT *ads, enum ndr_err_code ndr_push_server_id(struct ndr_push *ndr, int ndr_flags, const struct server_id *r); enum ndr_err_code ndr_pull_server_id(struct ndr_pull *ndr, int ndr_flags, struct server_id *r); void ndr_print_server_id(struct ndr_print *ndr, const char *name, const struct server_id *r); +enum ndr_err_code ndr_push_file_id(struct ndr_push *ndr, int ndr_flags, const struct file_id *r); +enum ndr_err_code ndr_pull_file_id(struct ndr_pull *ndr, int ndr_flags, struct file_id *r); +void ndr_print_file_id(struct ndr_print *ndr, const char *name, const struct file_id *r); _PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b); _PUBLIC_ void ndr_print_sockaddr_storage(struct ndr_print *ndr, const char *name, const struct sockaddr_storage *ss); const char *ndr_errstr(enum ndr_err_code err); diff --git a/source3/librpc/gen_ndr/ndr_notify.c b/source3/librpc/gen_ndr/ndr_notify.c index 00ba8bc293..d4ac42e961 100644 --- a/source3/librpc/gen_ndr/ndr_notify.c +++ b/source3/librpc/gen_ndr/ndr_notify.c @@ -10,6 +10,8 @@ _PUBLIC_ enum ndr_err_code ndr_push_notify_entry(struct ndr_push *ndr, int ndr_f NDR_CHECK(ndr_push_server_id(ndr, NDR_SCALARS, &r->server)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->filter)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->subdir_filter)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->dir_fd)); + NDR_CHECK(ndr_push_file_id(ndr, NDR_SCALARS, &r->dir_id)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM); @@ -21,6 +23,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_notify_entry(struct ndr_push *ndr, int ndr_f } if (ndr_flags & NDR_BUFFERS) { NDR_CHECK(ndr_push_server_id(ndr, NDR_BUFFERS, &r->server)); + NDR_CHECK(ndr_push_file_id(ndr, NDR_BUFFERS, &r->dir_id)); } return NDR_ERR_SUCCESS; } @@ -32,6 +35,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_notify_entry(struct ndr_pull *ndr, int ndr_f NDR_CHECK(ndr_pull_server_id(ndr, NDR_SCALARS, &r->server)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->filter)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->subdir_filter)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->dir_fd)); + NDR_CHECK(ndr_pull_file_id(ndr, NDR_SCALARS, &r->dir_id)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM); @@ -43,6 +48,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_notify_entry(struct ndr_pull *ndr, int ndr_f } if (ndr_flags & NDR_BUFFERS) { NDR_CHECK(ndr_pull_server_id(ndr, NDR_BUFFERS, &r->server)); + NDR_CHECK(ndr_pull_file_id(ndr, NDR_BUFFERS, &r->dir_id)); } return NDR_ERR_SUCCESS; } @@ -54,6 +60,8 @@ _PUBLIC_ void ndr_print_notify_entry(struct ndr_print *ndr, const char *name, co ndr_print_server_id(ndr, "server", &r->server); ndr_print_uint32(ndr, "filter", r->filter); ndr_print_uint32(ndr, "subdir_filter", r->subdir_filter); + ndr_print_uint32(ndr, "dir_fd", r->dir_fd); + ndr_print_file_id(ndr, "dir_id", &r->dir_id); ndr_print_string(ndr, "path", r->path); ndr_print_uint32(ndr, "path_len", r->path_len); ndr_print_pointer(ndr, "private_data", r->private_data); diff --git a/source3/librpc/gen_ndr/notify.h b/source3/librpc/gen_ndr/notify.h index c809702e5d..a5ec4a46e6 100644 --- a/source3/librpc/gen_ndr/notify.h +++ b/source3/librpc/gen_ndr/notify.h @@ -9,6 +9,8 @@ struct notify_entry { struct server_id server; uint32_t filter; uint32_t subdir_filter; + uint32_t dir_fd; + struct file_id dir_id; const char * path;/* [flag(LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM)] */ uint32_t path_len; void* private_data; diff --git a/source3/librpc/idl/notify.idl b/source3/librpc/idl/notify.idl index c4e633c254..550783b5cd 100644 --- a/source3/librpc/idl/notify.idl +++ b/source3/librpc/idl/notify.idl @@ -18,6 +18,8 @@ interface notify server_id server; uint32 filter; /* filter to apply in this directory */ uint32 subdir_filter; /* filter to apply in child directories */ + uint32 dir_fd; /* fd of open directory */ + file_id dir_id; /* file_id of open directory */ utf8string path; uint32 path_len; /* saves some computation on search */ pointer private_data; diff --git a/source3/librpc/ndr/util.c b/source3/librpc/ndr/util.c index 5afc4f4f5a..8fac5eadd4 100644 --- a/source3/librpc/ndr/util.c +++ b/source3/librpc/ndr/util.c @@ -155,6 +155,45 @@ void ndr_print_server_id(struct ndr_print *ndr, const char *name, const struct s ndr->depth--; } +enum ndr_err_code ndr_push_file_id(struct ndr_push *ndr, int ndr_flags, const struct file_id *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS, + (uint64_t)r->devid)); + NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS, + (uint64_t)r->inode)); + NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS, + (uint64_t)r->extid)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_file_id(struct ndr_pull *ndr, int ndr_flags, struct file_id *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->devid)); + NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->inode)); + NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->extid)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +void ndr_print_file_id(struct ndr_print *ndr, const char *name, const struct file_id *r) +{ + ndr_print_struct(ndr, name, "file_id"); + ndr->depth++; + ndr_print_udlong(ndr, "devid", (uint64_t)r->devid); + ndr_print_udlong(ndr, "inode", (uint64_t)r->inode); + ndr_print_udlong(ndr, "extid", (uint64_t)r->extid); + ndr->depth--; +} + _PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b) { ndr->print(ndr, "%-25s: %s", name, b?"true":"false"); diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 1d4f5e8c5b..e360af9ef5 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -214,6 +214,8 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter, ZERO_STRUCT(e); e.path = fullpath; + e.dir_fd = fsp->fh->fd; + e.dir_id = fsp->file_id; e.filter = filter; e.subdir_filter = 0; if (recursive) { -- cgit From 9a90cbea83548bffb224151a24005cb916f238f5 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Tue, 17 Feb 2009 16:20:18 -0800 Subject: s3: Make change notify immediately return a catch-all packet on underlying error * This allows a problem in the underlying CN backend to be bubbled up to the general CN layer so a catch-all reply can be returned * We now also return a catch-all response immediately if the server-side event queue becomes too big --- source3/smbd/notify.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index e360af9ef5..8ceeaf5f55 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -372,13 +372,26 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name) if ((fsp->notify->num_changes > 1000) || (name == NULL)) { /* * The real number depends on the client buf, just provide a - * guard against a DoS here. + * guard against a DoS here. If name == NULL the CN backend is + * alerting us to a problem. Possibly dropped events. Clear + * queued changes and send the catch-all response to the client + * if a request is pending. */ TALLOC_FREE(fsp->notify->changes); fsp->notify->num_changes = -1; + if (fsp->notify->requests != NULL) { + change_notify_reply(fsp->conn, + fsp->notify->requests->req, + fsp->notify->requests->max_param, + fsp->notify); + change_notify_remove_request(fsp->notify->requests); + } return; } + /* If we've exceeded the server side queue or received a NULL name + * from the underlying CN implementation, don't queue up any more + * requests until we can send a catch-all response to the client */ if (fsp->notify->num_changes == -1) { return; } -- cgit From 5bd7f9c61bb2fea1867ac6657c9b30799ba49d8f Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 20 Feb 2009 13:25:17 -0800 Subject: s3: OneFS implementation of change notify The OneFS Samba implementation of change notify is modeled after the usage of Linux's inotify kernel subsystem. A single call is made into the onefs.so VFS module to initialize kernel tracking of certain file change events. When these events occur a kernel notification is sent to smbd and the notification event is translated and given to the general Samba Change Notify layer through a callback function. The most difficult aspect is converting an SMB CompletionFilter to a matching ifs_event mask, and then back to an appropriate change notify action. Currently, not all possible cases are handled by the this module, but the most prevalent ones, which are tested by smbtorture, are implemented. --- source3/Makefile.in | 5 +- source3/modules/onefs.h | 9 + source3/modules/onefs_notify.c | 680 +++++++++++++++++++++++++++++++++++++++++ source3/modules/vfs_onefs.c | 2 + 4 files changed, 694 insertions(+), 2 deletions(-) create mode 100644 source3/modules/onefs_notify.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 6ff90fc815..2df995fb20 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -621,7 +621,8 @@ PROFILES_OBJ = utils/profiles.o \ $(LIB_OBJ) $(LIB_DUMMY_OBJ) \ $(POPT_LIB_OBJ) -OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o smbd/oplock_onefs.o +OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \ + smbd/oplock_onefs.o NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o @@ -666,7 +667,7 @@ VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \ modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.c \ - modules/onefs_cbrl.o + modules/onefs_cbrl.o modules/onefs_notify.o VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow_copy.o PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o PERFCOUNT_TEST_OBJ = modules/perfcount_test.o diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index c002739f1f..ea452a454d 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -204,6 +204,15 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, struct lock_struct *plock, struct blocking_lock_record *blr); +NTSTATUS onefs_notify_watch(vfs_handle_struct *vfs_handle, + struct sys_notify_context *ctx, + struct notify_entry *e, + void (*callback)(struct sys_notify_context *ctx, + void *private_data, + struct notify_event *ev), + void *private_data, + void *handle_p); + NTSTATUS onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc); diff --git a/source3/modules/onefs_notify.c b/source3/modules/onefs_notify.c new file mode 100644 index 0000000000..40f690876d --- /dev/null +++ b/source3/modules/onefs_notify.c @@ -0,0 +1,680 @@ +/* + * Unix SMB/CIFS implementation. + * + * Support for change notify using OneFS's file event notification system + * + * Copyright (C) Andrew Tridgell, 2006 + * Copyright (C) Steven Danneman, 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* Implement handling of change notify requests on files and directories using + * Isilon OneFS's "ifs event" file notification system. + * + * The structure of this file is based off the implementation of change notify + * using the inotify system calls in smbd/notify_inotify.c */ + +/* TODO: We could reduce the number of file descriptors used by merging + * multiple watch requests on the same directory into the same + * onefs_notify_watch_context. To do this we'd need mux/demux routines that + * when receiving an event on that watch context would check it against the + * CompletionFilter and WatchTree of open SMB requests, and return notify + * events back to the proper SMB requests */ + +#include "onefs.h" + +#include +#include +#include + +#include + +#define ONEFS_IFS_EVENT_MAX_NUM 8 +#define ONEFS_IFS_EVENT_MAX_BYTES (ONEFS_IFS_EVENT_MAX_NUM * \ + sizeof(struct ifs_event)) + +struct onefs_notify_watch_context { + struct sys_notify_context *ctx; + int watch_fd; + ino_t watch_lin; + const char *path; + int ifs_event_fd; + uint32_t ifs_filter; /* the ifs event mask */ + uint32_t smb_filter; /* the windows completion filter */ + void (*callback)(struct sys_notify_context *ctx, + void *private_data, + struct notify_event *ev); + void *private_data; +}; + +/** + * Conversion map from a SMB completion filter to an IFS event mask. + */ +static const struct { + uint32_t smb_filter; + uint32_t ifs_filter; +} onefs_notify_conv[] = { + {FILE_NOTIFY_CHANGE_FILE_NAME, + NOTE_CREATE | NOTE_DELETE | NOTE_RENAME_FROM | NOTE_RENAME_TO}, + {FILE_NOTIFY_CHANGE_DIR_NAME, + NOTE_CREATE | NOTE_DELETE | NOTE_RENAME_FROM | NOTE_RENAME_TO}, + {FILE_NOTIFY_CHANGE_ATTRIBUTES, + NOTE_CREATE | NOTE_DELETE | NOTE_RENAME_FROM | NOTE_RENAME_TO | + NOTE_ATTRIB}, + {FILE_NOTIFY_CHANGE_SIZE, + NOTE_SIZE | NOTE_EXTEND}, + {FILE_NOTIFY_CHANGE_LAST_WRITE, + NOTE_WRITE | NOTE_ATTRIB}, + /* OneFS doesn't set atime by default, but we can somewhat fake it by + * notifying for other events that imply ACCESS */ + {FILE_NOTIFY_CHANGE_LAST_ACCESS, + NOTE_WRITE | NOTE_ATTRIB}, + /* We don't have an ifs_event for the setting of create time, but we + * can fake by notifying when a "new" file is created via rename */ + {FILE_NOTIFY_CHANGE_CREATION, + NOTE_RENAME_TO}, + {FILE_NOTIFY_CHANGE_SECURITY, + NOTE_SECURITY}, + /* Unsupported bits + FILE_NOTIFY_CHANGE_EA (no EAs in OneFS) + FILE_NOTIFY_CHANGE_STREAM_NAME (no ifs_event equivalent) + FILE_NOTIFY_CHANGE_STREAM_SIZE (no ifs_event equivalent) + FILE_NOTIFY_CHANGE_STREAM_WRITE (no ifs_event equivalent) */ +}; + +#define ONEFS_NOTIFY_UNSUPPORTED (FILE_NOTIFY_CHANGE_LAST_ACCESS | \ + FILE_NOTIFY_CHANGE_CREATION | \ + FILE_NOTIFY_CHANGE_EA | \ + FILE_NOTIFY_CHANGE_STREAM_NAME | \ + FILE_NOTIFY_CHANGE_STREAM_SIZE | \ + FILE_NOTIFY_CHANGE_STREAM_WRITE) + +/** + * Convert Windows/SMB filter/flags to IFS event filter. + * + * @param[in] smb_filter Windows Completion Filter sent in the SMB + * + * @return ifs event filter mask + */ +static uint32_t +onefs_notify_smb_filter_to_ifs_filter(uint32_t smb_filter) +{ + int i; + uint32_t ifs_filter = 0x0; + + for (i=0;iMoveFile needs to send a modified + * notification on the new file, if smb_filter == ATTRIBUTES. + * Here we handle the case where two separate ATTR & NAME notifications + * have been registered. We handle the case where both bits are set in + * the same registration in onefs_notify_dispatch() */ + if ((smb_filter & FILE_NOTIFY_CHANGE_ATTRIBUTES) && + !(smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) && + (ifs_filter & NOTE_FILE) && (ifs_filter & NOTE_RENAME_TO)) + { + return NOTIFY_ACTION_MODIFIED; + } + + /* Special case 2: Writes need to send a modified + * notification on the file, if smb_filter = ATTRIBUTES. */ + if ((smb_filter & FILE_NOTIFY_CHANGE_ATTRIBUTES) && + (ifs_filter & NOTE_FILE) && (ifs_filter & NOTE_WRITE)) + { + return NOTIFY_ACTION_MODIFIED; + } + + /* Loop because some events may be filtered out. Eventually all + * relevant events will be taken care of and returned. */ + while (1) { + if (ifs_filter & NOTE_CREATE) { + ifs_filter &= ~NOTE_CREATE; + if ((smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) && + (ifs_filter & NOTE_FILE)) + return NOTIFY_ACTION_ADDED; + if ((smb_filter & FILE_NOTIFY_CHANGE_DIR_NAME) && + (ifs_filter & NOTE_DIRECTORY)) + return NOTIFY_ACTION_ADDED; + } + else if (ifs_filter & NOTE_DELETE) { + ifs_filter &= ~NOTE_DELETE; + if ((smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) && + (ifs_filter & NOTE_FILE)) + return NOTIFY_ACTION_REMOVED; + if ((smb_filter & FILE_NOTIFY_CHANGE_DIR_NAME) && + (ifs_filter & NOTE_DIRECTORY)) + return NOTIFY_ACTION_REMOVED; + } + else if (ifs_filter & NOTE_WRITE) { + ifs_filter &= ~NOTE_WRITE; + if ((smb_filter & FILE_NOTIFY_CHANGE_LAST_WRITE) || + (smb_filter & FILE_NOTIFY_CHANGE_LAST_ACCESS)) + return NOTIFY_ACTION_MODIFIED; + } + else if ((ifs_filter & NOTE_SIZE) || (ifs_filter & NOTE_EXTEND)) { + ifs_filter &= ~NOTE_SIZE; + ifs_filter &= ~NOTE_EXTEND; + + /* TODO: Do something on NOTE_DIR? */ + if ((smb_filter & FILE_NOTIFY_CHANGE_SIZE) && + (ifs_filter & NOTE_FILE)) + return NOTIFY_ACTION_MODIFIED; + } + else if (ifs_filter & NOTE_ATTRIB) { + ifs_filter &= ~NOTE_ATTRIB; + /* NOTE_ATTRIB needs to be converted to a + * LAST_WRITE as well, because we need to send + * LAST_WRITE when the mtime changes. Looking into + * better alternatives as this causes extra LAST_WRITE + * notifications. We also return LAST_ACCESS as a + * modification to attribs implies this. */ + if ((smb_filter & FILE_NOTIFY_CHANGE_ATTRIBUTES) || + (smb_filter & FILE_NOTIFY_CHANGE_LAST_WRITE) || + (smb_filter & FILE_NOTIFY_CHANGE_LAST_ACCESS)) + return NOTIFY_ACTION_MODIFIED; + } + else if (ifs_filter & NOTE_LINK) { + ifs_filter &= ~NOTE_LINK; + /* NOTE_LINK will send out NO notifications */ + } + else if (ifs_filter & NOTE_REVOKE) { + ifs_filter &= ~NOTE_REVOKE; + /* NOTE_REVOKE will send out NO notifications */ + } + else if (ifs_filter & NOTE_RENAME_FROM) { + ifs_filter &= ~NOTE_RENAME_FROM; + + if (((smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) && + (ifs_filter & NOTE_FILE)) || + ((smb_filter & FILE_NOTIFY_CHANGE_DIR_NAME) && + (ifs_filter & NOTE_DIRECTORY))) { + /* Check if this is a RENAME, not a MOVE */ + if (ifs_filter & NOTE_RENAME_SAMEDIR) { + /* Remove the NOTE_RENAME_SAMEDIR, IFF + * RENAME_TO is not in this event */ + if (!(ifs_filter & NOTE_RENAME_TO)) + ifs_filter &= + ~NOTE_RENAME_SAMEDIR; + return NOTIFY_ACTION_OLD_NAME; + } + return NOTIFY_ACTION_REMOVED; + } + } + else if (ifs_filter & NOTE_RENAME_TO) { + ifs_filter &= ~NOTE_RENAME_TO; + + if (((smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) && + (ifs_filter & NOTE_FILE)) || + ((smb_filter & FILE_NOTIFY_CHANGE_DIR_NAME) && + (ifs_filter & NOTE_DIRECTORY))) { + /* Check if this is a RENAME, not a MOVE */ + if (ifs_filter & NOTE_RENAME_SAMEDIR) { + /* Remove the NOTE_RENAME_SAMEDIR, IFF + * RENAME_FROM is not in this event */ + if (!(ifs_filter & NOTE_RENAME_FROM)) + ifs_filter &= + ~NOTE_RENAME_SAMEDIR; + return NOTIFY_ACTION_NEW_NAME; + } + return NOTIFY_ACTION_ADDED; + } + /* RAW-NOTIFY shows us that a rename triggers a + * creation time change */ + if ((smb_filter & FILE_NOTIFY_CHANGE_CREATION) && + (ifs_filter & NOTE_FILE)) + return NOTIFY_ACTION_MODIFIED; + } + else if (ifs_filter & NOTE_SECURITY) { + ifs_filter &= ~NOTE_SECURITY; + + if (smb_filter & FILE_NOTIFY_CHANGE_SECURITY) + return NOTIFY_ACTION_MODIFIED; + } else { + /* No relevant flags found */ + return 0; + } + } +} + +/** + * Retrieve a directory path of a changed file, relative to the watched dir + * + * @param[in] wc watch context for the returned event + * @param[in] e ifs_event notification returned from the kernel + * @param[out] path name relative to the watched dir. This is talloced + * off of wc and needs to be freed by the caller. + * + * @return true on success + * + * TODO: This function currently doesn't handle path names with multiple + * encodings. enc_get_lin_path() should be used in the future to convert + * each path segment's encoding to UTF-8 + */ +static bool +get_ifs_event_path(struct onefs_notify_watch_context *wc, struct ifs_event *e, + char **path) +{ + char *path_buf = NULL; + size_t pathlen = 0; + int error = 0; + + SMB_ASSERT(path); + + /* Lookup the path from watch_dir through our parent dir */ + if (e->namelen > 0) { + error = lin_get_path(wc->watch_lin, + e->parent_lin, + HEAD_SNAPID, + e->parent_parent_lin, + e->parent_name_hash, + &pathlen, &path_buf); + if (!error) { + /* Only add slash if a path exists in path_buf from + * lin_get_path call. Windows does not expect a + * leading '/' */ + if (pathlen > 0) + *path = talloc_asprintf(wc, "%s/%s", + path_buf, e->name); + else + *path = talloc_asprintf(wc, "%s", e->name); + SAFE_FREE(path_buf); + } + } + + /* If ifs_event didn't return a name, or we errored out of our intial + * path lookup, try again using the lin of the changed file */ + if (!(*path)) { + error = lin_get_path(wc->watch_lin, + e->lin, + HEAD_SNAPID, + e->parent_lin, + e->name_hash, + &pathlen, &path_buf); + if (error) { + /* It's possible that both the lin and the parent lin + * are invalid (or not given) -- we will skip these + * events. */ + DEBUG(3,("Path lookup failed. LINS are invalid: " + "e->lin: 0x%llu, e->parent_lin: 0x%llu, " + "e->parent_parent_lin: 0x%llu\n", + e->lin, e->parent_lin, e->parent_parent_lin)); + SAFE_FREE(path_buf); + return false; + } else { + *path = talloc_asprintf(wc, "%s", path_buf); + DEBUG(5, ("Using path from event LIN = %s\n", + path_buf)); + SAFE_FREE(path_buf); + } + } + + /* Replacement of UNIX slashes with WIN slashes is handled at a + * higher layer. */ + + return true; +} + +/** + * Dispatch one OneFS notify event to the general Samba code + * + * @param[in] wc watch context for the returned event + * @param[in] e event returned from the kernel + * + * @return nothing + */ +static void +onefs_notify_dispatch(struct onefs_notify_watch_context *wc, + struct ifs_event *e) +{ + char *path = NULL; + struct notify_event ne; + + DEBUG(5, ("Retrieved ifs event from kernel: lin=%#llx, ifs_events=%#x, " + "parent_lin=%#llx, namelen=%d, name=\"%s\"\n", + e->lin, e->events, e->parent_lin, e->namelen, e->name)); + + /* Check validity of event returned from kernel */ + if (e->lin == 0) { + /* The lin == 0 specifies 1 of 2 cases: + * 1) We are out of events. The kernel has a limited + * amount (somewhere near 90000) + * 2) Split nodes have merged back and had data written + * to them -- thus we've missed some of those events. */ + DEBUG(3, ("We've missed some kernel ifs events!\n")); + + /* Alert higher level to the problem so it returns catch-all + * response to the client */ + ne.path = NULL; + ne.action = 0; + wc->callback(wc->ctx, wc->private_data, &ne); + } + + if (e->lin == wc->watch_lin) { + /* Windows doesn't report notifications on root + * watched directory */ + /* TODO: This should be abstracted out to the general layer + * instead of being handled in every notify provider */ + DEBUG(5, ("Skipping notification on root of the watched " + "path.\n")); + return; + } + + /* Retrieve the full path for the ifs event name */ + if(!get_ifs_event_path(wc, e, &path)) { + DEBUG(3, ("Failed to convert the ifs_event lins to a path. " + "Skipping this event\n")); + return; + } + + if (!strncmp(path, ".ifsvar", 7)) { + /* Skip notifications on file if its in ifs configuration + * directory */ + goto clean; + } + + ne.path = path; + + /* Convert ifs event mask to an smb action mask */ + ne.action = onefs_notify_ifs_filter_to_smb_action(wc->smb_filter, + e->events); + + DEBUG(5, ("Converted smb_filter=%#x, ifs_events=%#x, to " + "ne.action = %d, for ne.path = %s\n", + wc->smb_filter, e->events, ne.action, ne.path)); + + if (!ne.action) + goto clean; + + /* Return notify_event to higher level */ + wc->callback(wc->ctx, wc->private_data, &ne); + + /* SMB expects a file rename/move to generate three actions, a + * rename_from/delete on the from file, a rename_to/create on the to + * file, and a modify for the rename_to file. If we have two separate + * notifications registered for ATTRIBUTES and FILENAME, this case will + * be handled by separate ifs_events in + * onefs_notify_ifs_filter_to_smb_action(). If both bits are registered + * in the same notification, we must send an extra MODIFIED action + * here. */ + if ((wc->smb_filter & FILE_NOTIFY_CHANGE_ATTRIBUTES) && + (wc->smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) && + (e->events & NOTE_FILE) && (e->events & NOTE_RENAME_TO)) + { + ne.action = NOTIFY_ACTION_MODIFIED; + wc->callback(wc->ctx, wc->private_data, &ne); + } + + /* FALLTHROUGH */ +clean: + talloc_free(path); + return; +} + +/** + * Callback when the kernel has some events for us + * + * Read events off ifs event fd and pass them to our dispatch function + * + * @param ev context of all tevents registered in the smbd + * @param fde tevent struct specific to one ifs event channel + * @param flags tevent flags passed when we added our ifs event channel fd to + * the main loop + * @param private_data onefs_notify_watch_context specific to this ifs event + * channel + * + * @return nothing + */ +static void +onefs_notify_handler(struct event_context *ev, + struct fd_event *fde, + uint16_t flags, + void *private_data) +{ + struct onefs_notify_watch_context *wc = NULL; + struct ifs_event ifs_events[ONEFS_IFS_EVENT_MAX_NUM]; + ssize_t nread = 0; + int count = 0; + int i = 0; + + wc = talloc_get_type(private_data, struct onefs_notify_watch_context); + + /* Read as many ifs events from the notify channel as we can */ + nread = sys_read(wc->ifs_event_fd, &ifs_events, + ONEFS_IFS_EVENT_MAX_BYTES); + if (nread == 0) { + DEBUG(0,("No data found while reading ifs event fd?!\n")); + return; + } + if (nread < 0) { + DEBUG(0,("Failed to read ifs event data: %s\n", + strerror(errno))); + return; + } + + count = nread / sizeof(struct ifs_event); + + DEBUG(5, ("Got %d notification events in %d bytes.\n", count, nread)); + + /* Dispatch ifs_events one-at-a-time to higher level */ + for (i=0; i < count; i++) { + onefs_notify_dispatch(wc, &ifs_events[i]); + } +} + +/** + * Destroy the ifs event channel + * + * This is called from talloc_free() when the generic Samba notify layer frees + * the onefs_notify_watch_context. + * + * @param[in] wc pointer to watch context which is being destroyed + * + * return 0 on success +*/ +static int +onefs_watch_destructor(struct onefs_notify_watch_context *wc) +{ + /* The ifs_event_fd will re de-registered from the event loop by + * another destructor triggered from the freeing of this wc */ + close(wc->ifs_event_fd); + return 0; +} + +/** + * Register a single change notify watch request. + * + * Open an event listener on a directory to watch for modifications. This + * channel is closed by a destructor when the caller calls talloc_free() + * on *handle. + * + * @param[in] vfs_handle handle given to most VFS operations + * @param[in] ctx context (conn and tevent) for this connection + * @param[in] e filter and path of client's notify request + * @param[in] callback function to call when file notification event is received + * from the kernel, passing that event up to Samba's + * generalized change notify layer + * @param[in] private_data opaque data given to us by the general change notify + * layer which must be returned in the callback function + * @param[out] handle_p handle returned to generalized change notify layer used + * to close the event channel when notification is + * cancelled + * + * @return NT_STATUS_OK unless error + */ +NTSTATUS +onefs_notify_watch(vfs_handle_struct *vfs_handle, + struct sys_notify_context *ctx, + struct notify_entry *e, + void (*callback)(struct sys_notify_context *ctx, + void *private_data, + struct notify_event *ev), + void *private_data, + void *handle_p) +{ + int ifs_event_fd = -1; + uint32_t ifs_filter = 0; + uint32_t smb_filter = e->filter; + bool watch_tree = !!e->subdir_filter; + struct onefs_notify_watch_context *wc = NULL; + void **handle = (void **)handle_p; + SMB_STRUCT_STAT sbuf; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + /* Fallback to default Samba implementation if kernel CN is disabled */ + if (!lp_kernel_change_notify(vfs_handle->conn->params)) { + (*handle) = NULL; + return NT_STATUS_OK; + } + + /* The OneFS open path should always give us a valid fd on a directory*/ + SMB_ASSERT(e->dir_fd >= 0); + + /* Always set e->filter to 0 so we don't fallback on the default change + * notify backend. It's not cluster coherent or cross-protocol so we + * can't guarantee correctness using it. */ + e->filter = 0; + e->subdir_filter = 0; + + /* Snapshots do not currently allow event listeners. See Isilon + * bug 33476 for an example of .snapshot debug spew that can occur. */ + if (e->dir_id.extid != HEAD_SNAPID) + return NT_STATUS_INVALID_PARAMETER; + + /* Convert Completion Filter mask to IFS Event mask */ + ifs_filter = onefs_notify_smb_filter_to_ifs_filter(smb_filter); + + if (smb_filter & ONEFS_NOTIFY_UNSUPPORTED) { + /* One or more of the filter bits could not be fully handled by + * the ifs_event system. To be correct, if we cannot service a + * bit in the completion filter we should return + * NT_STATUS_NOT_IMPLEMENTED to let the client know that they + * won't be receiving all the notify events that they asked for. + * Unfortunately, WinXP clients cache this error message, stop + * trying to send any notify requests at all, and instead return + * NOT_IMPLEMENTED to all requesting apps without ever sending a + * message to us. Thus we lie, and say we can service all bits, + * but simply don't return actions for the filter bits we can't + * detect or fully implement. */ + DEBUG(3,("One or more of the Windows completion filter bits " + "for \"%s\" could not be fully handled by the " + "ifs_event system. The failed bits are " + "smb_filter=%#x\n", + e->path, smb_filter & ONEFS_NOTIFY_UNSUPPORTED)); + } + + if (ifs_filter == 0) { + /* None of the filter bits given are supported by the ifs_event + * system. Don't create a kernel notify channel, but mock + * up a fake handle for the caller. */ + DEBUG(3,("No bits in the Windows completion filter could be " + "translated to ifs_event mask for \"%s\", " + "smb_filter=%#x\n", e->path, smb_filter)); + (*handle) = NULL; + return NT_STATUS_OK; + } + + /* Register an ifs event channel for this watch request */ + ifs_event_fd = ifs_create_listener(watch_tree ? + EVENT_RECURSIVE : + EVENT_CHILDREN, + ifs_filter, + e->dir_fd); + if (ifs_event_fd < 0) { + DEBUG(0,("Failed to create listener for %s with \"%s\". " + "smb_filter=0x%x, ifs_filter=0x%x, watch_tree=%u\n", + strerror(errno), e->path, smb_filter, ifs_filter, + watch_tree)); + return map_nt_error_from_unix(errno); + } + + /* Create a watch context to track this change notify request */ + wc = talloc(ctx, struct onefs_notify_watch_context); + if (wc == NULL) { + status = NT_STATUS_NO_MEMORY; + goto err; + } + + /* Get LIN for directory */ + if (sys_fstat(e->dir_fd, &sbuf)) { + DEBUG(0, ("stat on directory fd failed: %s\n", + strerror(errno))); + status = map_nt_error_from_unix(errno); + goto err; + } + + if (sbuf.st_ino == 0) { + DEBUG(0, ("0 LIN found!\n")); + goto err; + } + + wc->ctx = ctx; + wc->watch_fd = e->dir_fd; + wc->watch_lin = sbuf.st_ino; + wc->ifs_event_fd = ifs_event_fd; + wc->ifs_filter = ifs_filter; + wc->smb_filter = smb_filter; + wc->callback = callback; + wc->private_data = private_data; + wc->path = talloc_strdup(wc, e->path); + if (wc->path == NULL) { + status = NT_STATUS_NO_MEMORY; + goto err; + } + + (*handle) = wc; + + /* The caller frees the handle to stop watching */ + talloc_set_destructor(wc, onefs_watch_destructor); + + /* Add a tevent waiting for the ifs event fd to be readable */ + event_add_fd(ctx->ev, wc, wc->ifs_event_fd, EVENT_FD_READ, + onefs_notify_handler, wc); + + DEBUG(10, ("Watching for changes on \"%s\" smb_filter=0x%x, " + "ifs_filter=0x%x, watch_tree=%d, ifs_event_fd=%d, " + "dir_fd=%d, dir_lin=0x%llx\n", + e->path, smb_filter, ifs_filter, watch_tree, + ifs_event_fd, e->dir_fd, sbuf.st_ino)); + + return NT_STATUS_OK; + +err: + talloc_free(wc); + SMB_ASSERT(ifs_event_fd >= 0); + close(ifs_event_fd); + return status; +} diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index 522b94399d..f0c6a9d8bb 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -368,6 +368,8 @@ static vfs_op_tuple onefs_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_brl_cancel_windows), SMB_VFS_OP_BRL_CANCEL_WINDOWS, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(onefs_notify_watch), SMB_VFS_OP_NOTIFY_WATCH, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, -- cgit From 116ce19b10a1fd60776764974ad50776ff7c4714 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 20 Feb 2009 15:10:21 -0800 Subject: Moved become_daemon() and close_low_fds() to shared util lib --- lib/util/become_daemon.c | 22 ++++++++-------- lib/util/util.h | 9 ++++--- source3/Makefile.in | 3 ++- source3/include/proto.h | 2 -- source3/lib/util.c | 67 ------------------------------------------------ source4/smbd/server.c | 2 +- 6 files changed, 20 insertions(+), 85 deletions(-) diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c index 034114eade..5a97b65407 100644 --- a/lib/util/become_daemon.c +++ b/lib/util/become_daemon.c @@ -28,14 +28,15 @@ /******************************************************************* Close the low 3 fd's and open dev/null in their place. ********************************************************************/ -static void close_low_fds(bool stderr_too) + +_PUBLIC_ void close_low_fds(bool stderr_too) { #ifndef VALGRIND int fd; int i; close(0); - close(1); + close(1); if (stderr_too) close(2); @@ -61,11 +62,11 @@ static void close_low_fds(bool stderr_too) #endif } -/** +/**************************************************************************** Become a daemon, discarding the controlling terminal. -**/ +****************************************************************************/ -_PUBLIC_ void become_daemon(bool Fork) +_PUBLIC_ void become_daemon(bool Fork, bool no_process_group) { if (Fork) { if (fork()) { @@ -73,14 +74,14 @@ _PUBLIC_ void become_daemon(bool Fork) } } - /* detach from the terminal */ + /* detach from the terminal */ #ifdef HAVE_SETSID - setsid(); + if (!no_process_group) setsid(); #elif defined(TIOCNOTTY) - { - int i = open("/dev/tty", O_RDWR, 0); + if (!no_process_group) { + int i = sys_open("/dev/tty", O_RDWR, 0); if (i != -1) { - ioctl(i, (int) TIOCNOTTY, (char *)0); + ioctl(i, (int) TIOCNOTTY, (char *)0); close(i); } } @@ -90,4 +91,3 @@ _PUBLIC_ void become_daemon(bool Fork) close_low_fds(false); /* Don't close stderr, let the debug system attach it to the logfile */ } - diff --git a/lib/util/util.h b/lib/util/util.h index 7873f0e769..4d4df21600 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -724,12 +724,15 @@ _PUBLIC_ int idr_remove(struct idr_context *idp, int id); /* The following definitions come from lib/util/become_daemon.c */ -#if _SAMBA_BUILD_ == 4 +/** + Close the low 3 fd's and open dev/null in their place +**/ +_PUBLIC_ void close_low_fds(bool stderr_too); + /** Become a daemon, discarding the controlling terminal. **/ -_PUBLIC_ void become_daemon(bool fork); -#endif +_PUBLIC_ void become_daemon(bool fork, bool no_process_group); /** * Load a ini-style file. diff --git a/source3/Makefile.in b/source3/Makefile.in index 2df995fb20..98ed810f24 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -338,7 +338,8 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ ../lib/util/util_file.o ../lib/util/data_blob.o \ ../lib/util/util.o ../lib/util/fsusage.o \ ../lib/util/params.o ../lib/util/talloc_stack.o \ - ../lib/util/genrand.o ../lib/util/util_net.o + ../lib/util/genrand.o ../lib/util/util_net.o \ + ../lib/util/become_daemon.o CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 1ac2ac23fb..587bb29042 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1139,11 +1139,9 @@ int set_message_bcc(char *buf,int num_bytes); ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob); char *unix_clean_name(TALLOC_CTX *ctx, const char *s); char *clean_name(TALLOC_CTX *ctx, const char *s); -void close_low_fds(bool stderr_too); ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos); int set_blocking(int fd, bool set); void smb_msleep(unsigned int t); -void become_daemon(bool Fork, bool no_process_group); bool reinit_after_fork(struct messaging_context *msg_ctx, struct event_context *ev_ctx, bool parent_longlived); diff --git a/source3/lib/util.c b/source3/lib/util.c index 6079e71063..baac26b9aa 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -797,43 +797,6 @@ char *clean_name(TALLOC_CTX *ctx, const char *s) return unix_clean_name(ctx, str); } -/******************************************************************* - Close the low 3 fd's and open dev/null in their place. -********************************************************************/ - -void close_low_fds(bool stderr_too) -{ -#ifndef VALGRIND - int fd; - int i; - - close(0); - close(1); - - if (stderr_too) - close(2); - - /* try and use up these file descriptors, so silly - library routines writing to stdout etc won't cause havoc */ - for (i=0;i<3;i++) { - if (i == 2 && !stderr_too) - continue; - - fd = sys_open("/dev/null",O_RDWR,0); - if (fd < 0) - fd = sys_open("/dev/null",O_WRONLY,0); - if (fd < 0) { - DEBUG(0,("Can't open /dev/null\n")); - return; - } - if (fd != i) { - DEBUG(0,("Didn't get file descriptor %d\n",i)); - return; - } - } -#endif -} - /******************************************************************* Write data into an fd at a given offset. Ignore seek errors. ********************************************************************/ @@ -924,36 +887,6 @@ void smb_msleep(unsigned int t) #endif } -/**************************************************************************** - Become a daemon, discarding the controlling terminal. -****************************************************************************/ - -void become_daemon(bool Fork, bool no_process_group) -{ - if (Fork) { - if (sys_fork()) { - _exit(0); - } - } - - /* detach from the terminal */ -#ifdef HAVE_SETSID - if (!no_process_group) setsid(); -#elif defined(TIOCNOTTY) - if (!no_process_group) { - int i = sys_open("/dev/tty", O_RDWR, 0); - if (i != -1) { - ioctl(i, (int) TIOCNOTTY, (char *)0); - close(i); - } - } -#endif /* HAVE_SETSID */ - - /* Close fd's 0,1,2. Needed if started by rsh */ - close_low_fds(False); /* Don't close stderr, let the debug system - attach it to the logfile */ -} - bool reinit_after_fork(struct messaging_context *msg_ctx, struct event_context *ev_ctx, bool parent_longlived) diff --git a/source4/smbd/server.c b/source4/smbd/server.c index 247a10f60f..d576782ab1 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -277,7 +277,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ if (opt_daemon) { DEBUG(3,("Becoming a daemon.\n")); - become_daemon(true); + become_daemon(true, false); } cleanup_tmp_files(cmdline_lp_ctx); -- cgit From 193be432a224918bf0fbecfb6705146476c15c07 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 20 Feb 2009 16:24:08 -0800 Subject: s3: Refactor of madvise() usage in c441f58d * move to reinit_after_fork() to protect all Samba daemons * only protect parent processes --- source3/lib/util.c | 7 +++++++ source3/smbd/server.c | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source3/lib/util.c b/source3/lib/util.c index baac26b9aa..cda1fb474d 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -899,6 +899,13 @@ bool reinit_after_fork(struct messaging_context *msg_ctx, * numbers as each other */ set_need_random_reseed(); +#ifdef WITH_MADVISE_PROTECTED + /* Protect parent process from being killed by kernel when system + * memory is low. Child processes can still be killed */ + if(!parent_longlived) + madvise(NULL,0,MADV_PROTECT); +#endif + /* tdb needs special fork handling */ if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index e8ccba0873..28ce80b6c8 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -359,10 +359,6 @@ static void smbd_accept_connection(struct tevent_context *ev, /* Child code ... */ am_parent = 0; -#ifdef WITH_MADVISE_PROTECTED - madvise(NULL,0,MADV_PROTECT); -#endif - /* Stop zombies, the parent explicitly handles * them, counting worker smbds. */ CatchChild(); @@ -1135,9 +1131,6 @@ extern void build_options(bool screen); if (is_daemon && !interactive) { DEBUG( 3, ( "Becoming a daemon.\n" ) ); become_daemon(Fork, no_process_group); -#ifdef WITH_MADVISE_PROTECTED - madvise(NULL,0,MADV_PROTECT); -#endif } #if HAVE_SETPGID -- cgit From d9a842b26f306a6328e0fb4f226ed8292a8c221a Mon Sep 17 00:00:00 2001 From: todd stecher Date: Thu, 19 Feb 2009 09:33:30 -0800 Subject: S3: Detect max_open_files from system - Attempt to use syscalls to determine max-open-files value. - Add in periodic logging when max file limit reached --- source3/configure.in | 19 +++++++++++++++++++ source3/param/loadparm.c | 38 +++++++++++++++++++++++++++++++++++++- source3/smbd/open.c | 12 ++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index b163a9dbb8..624862fc89 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -836,6 +836,25 @@ if test x"$samba_cv_msghdr_msg_control" = x"yes"; then [If we can use msg_control for passing file descriptors]) fi +############################################# +# check for sysctlbyname +AC_CACHE_CHECK([for sysctlbyname],samba_cv_sysctlbyname, [ + AC_TRY_COMPILE([ +#include +#include +#include +#include ], +[ + int sysctl_max; + size_t size = sizeof(sysctl_max); + sysctlbyname("test", &sysctl_max, &size, NULL, 0); +], + samba_cv_sysctlbyname=yes,samba_cv_sysctlbyname=no)]) +if test x"$samba_cv_msghdr_msg_control" = x"yes"; then + AC_DEFINE(HAVE_SYSCTLBYNAME,1, + [If we support sysctlbyname api]) +fi + ############################################# # check for fd passing struct via msg_acctrights AC_CACHE_CHECK([for fd passing via msg_acctrights], diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 37af7038c1..cb568256c7 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4657,6 +4657,42 @@ static void init_printer_values(struct service *pService) } } +/** + * Function to return the default value for the maximum number of open + * file descriptors permitted. This function tries to consult the + * kernel-level (sysctl) and ulimit (getrlimit()) values and goes + * the smaller of those. + */ +static int max_open_files(void) +{ + int sysctl_max; + struct rlimit rl; + bool sysctl_worked = false, rlimit_worked = false; + +#ifdef HAVE_SYSCTLBYNAME + size_t size = sizeof(sysctl_max); + if (sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,0)==0) + sysctl_worked = true; +#endif + + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) + rlimit_worked = true; + + if (sysctl_worked) { + if ((!rlimit_worked) || + (rl.rlim_cur == RLIM_INFINITY) || + (rl.rlim_cur > sysctl_max)) + return sysctl_max; + else + return rl.rlim_cur; + } else { + if ((!rlimit_worked) || + (rl.rlim_cur == RLIM_INFINITY)) + return MAX_OPEN_FILES; + else + return rl.rlim_cur; + } +} /** * Common part of freeing allocated data for one parameter. @@ -4880,7 +4916,7 @@ static void init_globals(bool first_time_only) Globals.getwd_cache = true; Globals.bLargeReadwrite = True; Globals.max_log_size = 5000; - Globals.max_open_files = MAX_OPEN_FILES; + Globals.max_open_files = max_open_files(); Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE; Globals.maxprotocol = PROTOCOL_NT1; Globals.minprotocol = PROTOCOL_CORE; diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 239d4ff0c4..ac7c35c240 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -132,6 +132,18 @@ static NTSTATUS fd_open(struct connection_struct *conn, fsp->fh->fd = SMB_VFS_OPEN(conn,fname,fsp,flags,mode); if (fsp->fh->fd == -1) { status = map_nt_error_from_unix(errno); + if (errno == EMFILE) { + static time_t last_warned = 0L; + + if (time((time_t *) NULL) > last_warned) { + DEBUG(0,("Too many open files, unable " + "to open more! smbd's max " + "open files = %d\n", + lp_max_open_files())); + last_warned = time((time_t *) NULL); + } + } + } DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", -- cgit From 87a4c09b9bd37a967abcf874888a5d5161e7434f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Feb 2009 16:41:41 -0800 Subject: Change smbc_set_credentials_with_fallback() (unreleased) to use const approptiately. Jeremy. --- source3/include/libsmbclient.h | 6 +++--- source3/libsmb/libsmb_context.c | 21 ++++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index efc471c85b..8c642b1794 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -2692,9 +2692,9 @@ smbc_set_credentials(char *workgroup, void smbc_set_credentials_with_fallback(SMBCCTX *ctx, - char *workgroup, - char *user, - char *password); + const char *workgroup, + const char *user, + const char *password); /** * @ingroup structure diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index e4df7fcb08..c7c9903b76 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -654,9 +654,9 @@ smbc_set_credentials(char *workgroup, } void smbc_set_credentials_with_fallback(SMBCCTX *context, - char *workgroup, - char *user, - char *password) + const char *workgroup, + const char *user, + const char *password) { smbc_bool use_kerberos = false; const char *signing_state = "off"; @@ -681,11 +681,18 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, signing_state = "force"; } - smbc_set_credentials(workgroup, - user, - password, + /* Using CONST_DISCARD here is ugly, but + * we know that smbc_set_credentials() doesn't + * actually modify the strings, and should have + * been const from the start. We're constrained + * by the ABI here. + */ + + smbc_set_credentials(CONST_DISCARD(char *,workgroup), + CONST_DISCARD(char *,user), + CONST_DISCARD(char *,password), use_kerberos, - (char *)signing_state); + CONST_DISCARD(char *,signing_state)); if (smbc_getOptionFallbackAfterKerberos(context)) { cli_cm_set_fallback_after_kerberos(); -- cgit From 5300dc62888dfd36479353f4a6ea5cb52728c754 Mon Sep 17 00:00:00 2001 From: Zack Kirsch Date: Fri, 20 Feb 2009 15:20:39 -0800 Subject: s3 OneFS: Add debugging for createfile_flags --- source3/modules/onefs_system.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 6f93d9ff97..3a86b4b815 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -123,17 +123,29 @@ int onefs_sys_create_file(connection_struct *conn, /* Convert samba dos flags to UF_DOS_* attributes. */ onefs_dos_attributes = dos_attributes_to_stat_dos_flags(dos_flags); + /** + * Deal with kernel creating Default ACLs. (Isilon bug 47447.) + * + * 1) "nt acl support = no", default_acl = no + * 2) "inherit permissions = yes", default_acl = no + */ + if (lp_nt_acl_support(SNUM(conn)) && !lp_inherit_perms(SNUM(conn))) + cf_flags = cf_flags_or(cf_flags, CF_FLAGS_DEFAULT_ACL); + DEBUG(10,("onefs_sys_create_file: base_fd = %d, " - "open_access_mask = 0x%x, flags = 0x%x, mode = 0x%x, " + "open_access_mask = 0x%x, flags = 0x%x, mode = 0%o, " "desired_oplock = %s, id = 0x%x, secinfo = 0x%x, sd = %p, " - "dos_attributes = 0x%x, path = %s\n", base_fd, + "dos_attributes = 0x%x, path = %s, " + "default_acl=%s\n", base_fd, (unsigned int)open_access_mask, (unsigned int)flags, (unsigned int)mode, onefs_oplock_str(onefs_oplock), (unsigned int)id, (unsigned int)secinfo, sd, - (unsigned int)onefs_dos_attributes, path)); + (unsigned int)onefs_dos_attributes, path, + cf_flags_and_bool(cf_flags, CF_FLAGS_DEFAULT_ACL) ? + "true" : "false")); /* Initialize smlock struct for files/dirs but not internal opens */ if (!(oplock_request & INTERNAL_OPEN_ONLY)) { @@ -144,15 +156,6 @@ int onefs_sys_create_file(connection_struct *conn, smlock_dump(10, psml); - /** - * Deal with kernel creating Default ACLs. (Isilon bug 47447.) - * - * 1) "nt acl support = no", default_acl = no - * 2) "inherit permissions = yes", default_acl = no - */ - if (lp_nt_acl_support(SNUM(conn)) && !lp_inherit_perms(SNUM(conn))) - cf_flags = cf_flags_or(cf_flags, CF_FLAGS_DEFAULT_ACL); - ret_fd = ifs_createfile(base_fd, path, (enum ifs_ace_rights)open_access_mask, flags & ~O_ACCMODE, mode, onefs_oplock, id, psml, secinfo, pifs_sd, onefs_dos_attributes, -- cgit From a04bb5f9a267c6945db6ff25e16d15f7f813aaaf Mon Sep 17 00:00:00 2001 From: Zack Kirsch Date: Fri, 20 Feb 2009 15:22:15 -0800 Subject: s3 BRL: Add more clarifying comments and add implied logic to make conditional more clear --- source3/locking/brlock.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index d12c4affc3..aa522ac780 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -74,6 +74,7 @@ bool brl_same_context(const struct lock_context *ctx1, static bool brl_overlap(const struct lock_struct *lck1, const struct lock_struct *lck2) { + /* XXX Remove for Win7 compatibility. */ /* this extra check is not redundent - it copes with locks that go beyond the end of 64 bit file space */ if (lck1->size != 0 && @@ -105,8 +106,11 @@ static bool brl_conflict(const struct lock_struct *lck1, return False; } - if (brl_same_context(&lck1->context, &lck2->context) && - lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) { + /* A READ lock can stack on top of a WRITE lock if they have the same + * context & fnum. */ + if (lck1->lock_type == WRITE_LOCK && lck2->lock_type == READ_LOCK && + brl_same_context(&lck1->context, &lck2->context) && + lck1->fnum == lck2->fnum) { return False; } -- cgit From 2539d678f54d09577d5c86fae1d6d43175bfca96 Mon Sep 17 00:00:00 2001 From: Zack Kirsch Date: Fri, 20 Feb 2009 15:29:29 -0800 Subject: s4 torture: Add comment to clarify test --- source4/torture/raw/samba3misc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c index 8cdccb3906..c4c790cb0a 100644 --- a/source4/torture/raw/samba3misc.c +++ b/source4/torture/raw/samba3misc.c @@ -672,6 +672,9 @@ bool torture_samba3_caseinsensitive(struct torture_context *torture) /* * Check that Samba3 correctly deals with conflicting posix byte range locks * on an underlying file + * + * Note: This test depends on "posix locking = yes". + * Note: To run this test, use "--option=torture:localdir=" */ bool torture_samba3_posixtimedlock(struct torture_context *tctx) -- cgit From e311dcff2272968959b4268c2e7aad351443b191 Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Tue, 9 Dec 2008 08:29:26 +0000 Subject: Allow building with an external libwbclient library Introduce a new configure option --with-wbclient which specifies a location to find a compatible libwbclient library to link against. This options is overwritten by --with-winbind --- source3/configure.in | 77 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 624862fc89..9320fb64e4 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -5732,6 +5732,34 @@ AC_MSG_CHECKING(whether to build winbind) # Initially, the value of $host_os decides whether winbind is supported HAVE_WINBIND=yes +HAVE_WBCLIENT=no + +# Define external wbclient library to link against. This disables winbind. +# We define this here so --with-winbind can override it. +AC_ARG_WITH(wbclient, +[AS_HELP_STRING([--with-wbclient], [Use external wbclient (optional)])], +[ + case "$withval" in + no) + HAVE_WBCLIENT=no + ;; + yes) + HAVE_WBCLIENT=yes + HAVE_WINBIND=no + ;; + *) + HAVE_WBCLIENT=yes + HAVE_WINBIND=no + WBCLIENT_INCLUDES="-I$withval/include" + WBCLIENT_LDFLAGS="-L$withval/lib" + ;; + esac ], +) + +AC_SUBST(WBCLIENT_INCLUDES) +AC_SUBST(WBCLIENT_LDFLAGS) +AC_SUBST(WBCLIENT_LIBS) + # Define the winbind shared library name and any specific linker flags # it needs to be built with. @@ -5813,6 +5841,7 @@ AC_ARG_WITH(winbind, case "$withval" in yes) HAVE_WINBIND=yes + HAVE_WBCLIENT=no ;; no) HAVE_WINBIND=no @@ -5836,27 +5865,35 @@ if test x"$HAVE_WINBIND" = x"no"; then WINBIND_NSS="" WINBIND_WINS_NSS="" fi - -if test x"$enable_developer" = x"yes" -a x"$LINK_LIBWBCLIENT" = x"STATIC" ; then - BUILD_LIBWBCLIENT_SHARED=no -else - BUILD_LIBWBCLIENT_SHARED=yes -fi - -LIBWBCLIENT_SHARED_TARGET=bin/libwbclient.$SHLIBEXT -LIBWBCLIENT_STATIC_TARGET=bin/libwbclient.a -LIBWBCLIENT_SOVER=0 -if test $BLDSHARED = true -a x"$HAVE_WINBIND" = x"yes" -a x"$BUILD_LIBWBCLIENT_SHARED" = x"yes"; then - NSS_MODULES="${WINBIND_NSS} ${WINBIND_WINS_NSS}" - ## Only worry about libwbclient if we have shared library support - ## and winbindd - LIBWBCLIENT_SHARED=$LIBWBCLIENT_SHARED_TARGET - LIBWBCLIENT=libwbclient - INSTALL_LIBWBCLIENT=installlibwbclient - UNINSTALL_LIBWBCLIENT=uninstalllibwbclient - WINBIND_LIBS="-lwbclient" +if test x"$HAVE_WBCLIENT" = x"yes"; then + AC_CHECK_LIB(wbclient, wbcInterfaceDetails, + [WINBIND_LIBS="-lwbclient"], AC_MSG_ERROR([Could not find wbclient]), [$WBCLIENT_LDFLAGS]) + WINBIND_LIBS="$WINBIND_LIBS $WBCLIENT_LDFLAGS" + AC_MSG_RESULT(yes) + AC_DEFINE(WITH_WINBIND,1,[Whether to link to wbclient]) + EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/wbinfo\$(EXEEXT)" else - LIBWBCLIENT_STATIC=$LIBWBCLIENT_STATIC_TARGET + if test x"$enable_developer" = x"yes" -a x"$LINK_LIBWBCLIENT" = x"STATIC" ; then + BUILD_LIBWBCLIENT_SHARED=no + else + BUILD_LIBWBCLIENT_SHARED=yes + fi + + LIBWBCLIENT_SHARED_TARGET=bin/libwbclient.$SHLIBEXT + LIBWBCLIENT_STATIC_TARGET=bin/libwbclient.a + LIBWBCLIENT_SOVER=0 + if test $BLDSHARED = true -a x"$HAVE_WINBIND" = x"yes" -a x"$BUILD_LIBWBCLIENT_SHARED" = x"yes"; then + NSS_MODULES="${WINBIND_NSS} ${WINBIND_WINS_NSS}" + ## Only worry about libwbclient if we have shared + # library support + LIBWBCLIENT_SHARED=$LIBWBCLIENT_SHARED_TARGET + LIBWBCLIENT=libwbclient + INSTALL_LIBWBCLIENT=installlibwbclient + UNINSTALL_LIBWBCLIENT=uninstalllibwbclient + WINBIND_LIBS="-lwbclient" + else + LIBWBCLIENT_STATIC=$LIBWBCLIENT_STATIC_TARGET + fi fi if test x"$HAVE_WINBIND" = x"yes"; then -- cgit From c383022f89a34b83039502cc58178498cc06370e Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Fri, 13 Feb 2009 12:24:22 -0800 Subject: Introduce a new authentication backend auth_onefs_wb This new backend is custom tailored to onefs' unique requirements: 1) No fallback logic 2) Does not validate the domain of the user 3) Handles unencrypted passwords --- source3/Makefile.in | 5 ++ source3/auth/auth_onefs_wb.c | 134 +++++++++++++++++++++++++++++++++++++++++++ source3/configure.in | 2 + 3 files changed, 141 insertions(+) create mode 100644 source3/auth/auth_onefs_wb.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 98ed810f24..a0bd4ab303 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -685,6 +685,7 @@ AUTH_SAM_OBJ = auth/auth_sam.o AUTH_SERVER_OBJ = auth/auth_server.o AUTH_UNIX_OBJ = auth/auth_unix.o AUTH_WINBIND_OBJ = auth/auth_winbind.o +AUTH_ONEFS_WB_OBJ = auth/auth_onefs_wb.o AUTH_SCRIPT_OBJ = auth/auth_script.o AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o @@ -2343,6 +2344,10 @@ bin/winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WINBIND_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(AUTH_WINBIND_OBJ) +bin/onefs_wb.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_ONEFS_WB_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(AUTH_ONEFS_WB_OBJ) + bin/unix.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_UNIX_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(AUTH_UNIX_OBJ) diff --git a/source3/auth/auth_onefs_wb.c b/source3/auth/auth_onefs_wb.c new file mode 100644 index 0000000000..49de6966b0 --- /dev/null +++ b/source3/auth/auth_onefs_wb.c @@ -0,0 +1,134 @@ +/* + Unix SMB/CIFS implementation. + + Winbind authentication mechnism, customized for onefs + + Copyright (C) Tim Potter 2000 + Copyright (C) Andrew Bartlett 2001 - 2002 + Copyright (C) Dan Sledz 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +/* Authenticate a user with a challenge/response */ + +static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context, + void *my_private_data, + TALLOC_CTX *mem_ctx, + const auth_usersupplied_info *user_info, + auth_serversupplied_info **server_info) +{ + NTSTATUS nt_status; + wbcErr wbc_status; + struct wbcAuthUserParams params; + struct wbcAuthUserInfo *info = NULL; + struct wbcAuthErrorInfo *err = NULL; + + if (!user_info || !auth_context || !server_info) { + return NT_STATUS_INVALID_PARAMETER; + } + /* Send off request */ + + params.account_name = user_info->smb_name; + params.domain_name = user_info->domain; + params.workstation_name = user_info->wksta_name; + + params.flags = 0; + params.parameter_control= user_info->logon_parameters; + + /* Handle plaintext */ + if (!user_info->encrypted) { + DEBUG(3,("Checking plaintext password for %s.\n", + user_info->internal_username)); + params.level = WBC_AUTH_USER_LEVEL_PLAIN; + + params.password.plaintext = user_info->plaintext_password.data; + } else { + DEBUG(3,("Checking encrypted password for %s.\n", + user_info->internal_username)); + params.level = WBC_AUTH_USER_LEVEL_RESPONSE; + + memcpy(params.password.response.challenge, + auth_context->challenge.data, + sizeof(params.password.response.challenge)); + + params.password.response.nt_length = user_info->nt_resp.length; + params.password.response.nt_data = user_info->nt_resp.data; + params.password.response.lm_length = user_info->lm_resp.length; + params.password.response.lm_data = user_info->lm_resp.data; + + } + + /* we are contacting the privileged pipe */ + become_root(); + wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); + unbecome_root(); + + if (!WBC_ERROR_IS_OK(wbc_status)) { + DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n", + wbc_status, wbcErrorString(wbc_status))); + } + + if (wbc_status == WBC_ERR_NO_MEMORY) { + return NT_STATUS_NO_MEMORY; + } + + if (wbc_status == WBC_ERR_AUTH_ERROR) { + nt_status = NT_STATUS(err->nt_status); + wbcFreeMemory(err); + return nt_status; + } + + if (!WBC_ERROR_IS_OK(wbc_status)) { + return NT_STATUS_LOGON_FAILURE; + } + + DEBUG(10,("wbcAuthenticateUserEx succeeded\n")); + + nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, + user_info->smb_name, + user_info->domain, + info, server_info); + wbcFreeMemory(info); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + (*server_info)->nss_token |= user_info->was_mapped; + + return nt_status; +} + +/* module initialisation */ +static NTSTATUS auth_init_onefs_wb(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +{ + if (!make_auth_methods(auth_context, auth_method)) { + return NT_STATUS_NO_MEMORY; + } + + (*auth_method)->name = "onefs_wb"; + (*auth_method)->auth = check_onefs_wb_security; + + return NT_STATUS_OK; +} + +NTSTATUS auth_onefs_wb_init(void) +{ + return smb_register_auth(AUTH_INTERFACE_VERSION, "onefs_wb", auth_init_onefs_wb); +} diff --git a/source3/configure.in b/source3/configure.in index 9320fb64e4..41140aed34 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1104,6 +1104,7 @@ echo $samba_cv_HAVE_ONEFS if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS]) default_shared_modules="$default_shared_modules vfs_onefs vfs_onefs_shadow_copy perfcount_onefs" + default_static_modules="$default_static_modules auth_onefs_wb" ONEFS_LIBS="-lisi_acl -lisi_ecs -lisi_event -lisi_util" # Need to also add general libs for oplocks support save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat" @@ -6187,6 +6188,7 @@ SMB_SUBSYSTEM(CHARSET,lib/iconv.o) SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH) SMB_MODULE(auth_unix, \$(AUTH_UNIX_OBJ), "bin/unix.$SHLIBEXT", AUTH) SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH) +SMB_MODULE(auth_onefs_wb, \$(AUTH_ONEFS_WB_OBJ), "bin/onefs_wb.$SHLIBEXT", AUTH) SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH) SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH) SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH) -- cgit From fc02c3b0890a9549989bb0aba16588026c6d6b43 Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Fri, 13 Feb 2009 12:28:57 -0800 Subject: Introduce a new passdb backend: pdb_onefs_sam Implements a custom backend for onefs that exclusively uses the wbclient interface for all passdb calls. It lacks some features of a standard passdb. In particular it's a read only interface and doesn't implement privileges. --- source3/Makefile.in | 4 + source3/configure.in | 3 +- source3/passdb/pdb_onefs_sam.c | 433 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 source3/passdb/pdb_onefs_sam.c diff --git a/source3/Makefile.in b/source3/Makefile.in index a0bd4ab303..6087fa0359 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -2364,6 +2364,10 @@ bin/tdbsam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_tdb.o @echo "Building plugin $@" @$(SHLD_MODULE) passdb/pdb_tdb.o +bin/onefs_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_onefs_sam.o + @echo "Building plugin $@" + @$(SHLD_MODULE) passdb/pdb_onefs_sam.o + bin/smbpasswd.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_smbpasswd.o @echo "Building plugin $@" @$(SHLD_MODULE) passdb/pdb_smbpasswd.o diff --git a/source3/configure.in b/source3/configure.in index 41140aed34..7fe824c989 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1104,7 +1104,7 @@ echo $samba_cv_HAVE_ONEFS if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS]) default_shared_modules="$default_shared_modules vfs_onefs vfs_onefs_shadow_copy perfcount_onefs" - default_static_modules="$default_static_modules auth_onefs_wb" + default_static_modules="$default_static_modules auth_onefs_wb pdb_onefs_sam" ONEFS_LIBS="-lisi_acl -lisi_ecs -lisi_event -lisi_util" # Need to also add general libs for oplocks support save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat" @@ -6146,6 +6146,7 @@ SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o passdb/pdb_nds.o, "bin/ldapsam.$SHLIBEXT" [ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] ) SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB) SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB) +SMB_MODULE(pdb_onefs_sam, passdb/pdb_onefs_sam.o, "bin/onefs_sam.$SHLIBEXT", PDB) SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o) diff --git a/source3/passdb/pdb_onefs_sam.c b/source3/passdb/pdb_onefs_sam.c new file mode 100644 index 0000000000..51b8618aad --- /dev/null +++ b/source3/passdb/pdb_onefs_sam.c @@ -0,0 +1,433 @@ +/* + Unix SMB/CIFS implementation. + Password and authentication handling for wbclient + Copyright (C) Andrew Bartlett 2002 + Copyright (C) Jelmer Vernooij 2002 + Copyright (C) Simo Sorce 2003 + Copyright (C) Volker Lendecke 2006 + Copyright (C) Dan Sledz 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +/*************************************************************************** + Default implementations of some functions. + ****************************************************************************/ +static NTSTATUS _pdb_onefs_sam_getsampw(struct pdb_methods *methods, + struct samu *user, + const struct passwd *pwd) +{ + NTSTATUS result = NT_STATUS_OK; + + if (pwd == NULL) + return NT_STATUS_NO_SUCH_USER; + + memset(user, 0, sizeof(user)); + + /* Can we really get away with this little of information */ + user->methods = methods; + result = samu_set_unix(user, pwd); + + return result; +} + +static NTSTATUS pdb_onefs_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) +{ + return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwnam(sname)); +} + +static NTSTATUS pdb_onefs_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) +{ + return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwsid(sid)); +} + +static bool pdb_onefs_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, + DOM_SID *sid) +{ + return winbind_uid_to_sid(sid, uid); +} + +static bool pdb_onefs_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, + DOM_SID *sid) +{ + return winbind_gid_to_sid(sid, gid); +} + +static bool pdb_onefs_sam_sid_to_id(struct pdb_methods *methods, + const DOM_SID *sid, + union unid_t *id, enum lsa_SidType *type) +{ + if (winbind_sid_to_uid(&id->uid, sid)) { + *type = SID_NAME_USER; + } else if (winbind_sid_to_gid(&id->gid, sid)) { + /* We assume all gids are groups, not aliases */ + *type = SID_NAME_DOM_GRP; + } else { + return false; + } + + return true; +} + +static NTSTATUS pdb_onefs_sam_enum_group_members(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + const DOM_SID *group, + uint32 **pp_member_rids, + size_t *p_num_members) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + struct samu *user, + DOM_SID **pp_sids, + gid_t **pp_gids, + size_t *p_num_groups) +{ + size_t i; + const char *username = pdb_get_username(user); + + if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { + return NT_STATUS_NO_SUCH_USER; + } + + if (*p_num_groups == 0) { + smb_panic("primary group missing"); + } + + *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups); + + if (*pp_sids == NULL) { + TALLOC_FREE(*pp_gids); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i < *p_num_groups; i++) { + gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]); + } + + return NT_STATUS_OK; +} + +static NTSTATUS pdb_onefs_sam_lookup_rids(struct pdb_methods *methods, + const DOM_SID *domain_sid, + int num_rids, + uint32 *rids, + const char **names, + enum lsa_SidType *attrs) +{ + NTSTATUS result = NT_STATUS_OK; + char *domain = NULL; + char **account_names = NULL; + char name[256]; + enum lsa_SidType *attr_list = NULL; + int i; + + if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids, + (const char **)&domain, + (const char ***)&account_names, &attr_list)) + { + result = NT_STATUS_NONE_MAPPED; + goto done; + } + + memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType)); + + for (i=0; int_name, sizeof(map->nt_name), "%s%c%s", + domain, *lp_winbind_separator(), name); + map->sid_name_use = name_type; + map->sid = *sid; + map->gid = gid; + return true; +} + +static NTSTATUS pdb_onefs_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, + DOM_SID sid) +{ + NTSTATUS result = NT_STATUS_OK; + char *name = NULL; + char *domain = NULL; + enum lsa_SidType name_type; + gid_t gid; + + if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, + (const char **) &name, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_sid_to_gid(&gid, &sid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + TALLOC_FREE(name); + TALLOC_FREE(domain); + return result; +} + +static NTSTATUS pdb_onefs_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, + gid_t gid) +{ + NTSTATUS result = NT_STATUS_OK; + char *name = NULL; + char *domain = NULL; + DOM_SID sid; + enum lsa_SidType name_type; + + if (!winbind_gid_to_sid(&sid, gid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, + (const char **)&name, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + TALLOC_FREE(name); + TALLOC_FREE(domain); + + return result; +} + +static NTSTATUS pdb_onefs_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, + const char *name) +{ + NTSTATUS result = NT_STATUS_OK; + char *user_name = NULL; + char *domain = NULL; + DOM_SID sid; + gid_t gid; + enum lsa_SidType name_type; + + if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_sid_to_gid(&gid, &sid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + + return result; +} + +static NTSTATUS pdb_onefs_sam_enum_group_mapping(struct pdb_methods *methods, + const DOM_SID *sid, enum lsa_SidType sid_name_use, + GROUP_MAP **pp_rmap, size_t *p_num_entries, + bool unix_only) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_onefs_sam_get_aliasinfo(struct pdb_methods *methods, + const DOM_SID *sid, + struct acct_info *info) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_onefs_sam_enum_aliasmem(struct pdb_methods *methods, + const DOM_SID *alias, DOM_SID **pp_members, + size_t *p_num_members) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_onefs_sam_alias_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + const DOM_SID *domain_sid, + const DOM_SID *members, + size_t num_members, + uint32 **pp_alias_rids, + size_t *p_num_alias_rids) +{ + if (!winbind_get_sid_aliases(mem_ctx, domain_sid, + members, num_members, pp_alias_rids, p_num_alias_rids)) + return NT_STATUS_UNSUCCESSFUL; + + return NT_STATUS_OK; +} + +static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char *location) +{ + NTSTATUS result; + + if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) { + return result; + } + + (*pdb_method)->name = "onefs_sam"; + + (*pdb_method)->getsampwnam = pdb_onefs_sam_getsampwnam; + (*pdb_method)->getsampwsid = pdb_onefs_sam_getsampwsid; + + (*pdb_method)->getgrsid = pdb_onefs_sam_getgrsid; + (*pdb_method)->getgrgid = pdb_onefs_sam_getgrgid; + (*pdb_method)->getgrnam = pdb_onefs_sam_getgrnam; + (*pdb_method)->enum_group_mapping = pdb_onefs_sam_enum_group_mapping; + (*pdb_method)->enum_group_members = pdb_onefs_sam_enum_group_members; + (*pdb_method)->enum_group_memberships = pdb_onefs_sam_enum_group_memberships; + (*pdb_method)->get_aliasinfo = pdb_onefs_sam_get_aliasinfo; + (*pdb_method)->enum_aliasmem = pdb_onefs_sam_enum_aliasmem; + (*pdb_method)->enum_alias_memberships = pdb_onefs_sam_alias_memberships; + (*pdb_method)->lookup_rids = pdb_onefs_sam_lookup_rids; + (*pdb_method)->get_account_policy = pdb_onefs_sam_get_account_policy; + (*pdb_method)->set_account_policy = pdb_onefs_sam_set_account_policy; + (*pdb_method)->uid_to_sid = pdb_onefs_sam_uid_to_sid; + (*pdb_method)->gid_to_sid = pdb_onefs_sam_gid_to_sid; + (*pdb_method)->sid_to_id = pdb_onefs_sam_sid_to_id; + + (*pdb_method)->search_groups = pdb_onefs_sam_search_groups; + (*pdb_method)->search_aliases = pdb_onefs_sam_search_aliases; + + (*pdb_method)->get_trusteddom_pw = pdb_onefs_sam_get_trusteddom_pw; + (*pdb_method)->set_trusteddom_pw = pdb_onefs_sam_set_trusteddom_pw; + (*pdb_method)->del_trusteddom_pw = pdb_onefs_sam_del_trusteddom_pw; + (*pdb_method)->enum_trusteddoms = pdb_onefs_sam_enum_trusteddoms; + + (*pdb_method)->private_data = NULL; + (*pdb_method)->free_private_data = NULL; + + return NT_STATUS_OK; +} + +NTSTATUS pdb_onefs_sam_init(void) +{ + return smb_register_passdb(PASSDB_INTERFACE_VERSION, "onefs_sam", pdb_init_onefs_sam); +} -- cgit From c207fe42a796cf33f1901caeb2c4c1e493b94471 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 20 Feb 2009 23:25:49 -0800 Subject: s3: Fix build break in d9a842b2 * actually check for existance of sysctlbyname() --- source3/configure.in | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 7fe824c989..bd3d4af40b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -836,25 +836,6 @@ if test x"$samba_cv_msghdr_msg_control" = x"yes"; then [If we can use msg_control for passing file descriptors]) fi -############################################# -# check for sysctlbyname -AC_CACHE_CHECK([for sysctlbyname],samba_cv_sysctlbyname, [ - AC_TRY_COMPILE([ -#include -#include -#include -#include ], -[ - int sysctl_max; - size_t size = sizeof(sysctl_max); - sysctlbyname("test", &sysctl_max, &size, NULL, 0); -], - samba_cv_sysctlbyname=yes,samba_cv_sysctlbyname=no)]) -if test x"$samba_cv_msghdr_msg_control" = x"yes"; then - AC_DEFINE(HAVE_SYSCTLBYNAME,1, - [If we support sysctlbyname api]) -fi - ############################################# # check for fd passing struct via msg_acctrights AC_CACHE_CHECK([for fd passing via msg_acctrights], @@ -1063,6 +1044,9 @@ AC_SEARCH_LIBS(backtrace_symbols, [execinfo]) AC_CHECK_FUNCS(backtrace_symbols) AC_CHECK_LIB(exc, trace_back_stack) +# check for sysctlbyname for BSD systems +AC_CHECK_FUNCS(sysctlbyname) + printf "%s" "checking for GPFS GPL libs... " save_LIBS="$LIBS" LIBS="$LIBS -lgpfs_gpl" -- cgit From 25627234451735154d7c8a12ed920397d0371b1c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Feb 2009 12:49:01 +0100 Subject: Fix an uninitialized variable --- source3/param/loadparm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index cb568256c7..3d29f3afd9 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4665,7 +4665,7 @@ static void init_printer_values(struct service *pService) */ static int max_open_files(void) { - int sysctl_max; + int sysctl_max = MAX_OPEN_FILES; struct rlimit rl; bool sysctl_worked = false, rlimit_worked = false; -- cgit From 3305780e5d5d10a35e116f43efe47b8a94a9d3fd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 19 Feb 2009 23:26:06 +0100 Subject: Move some bytes from the data to the text segment --- source3/libsmb/libsmb_path.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index 3ea03446d8..6a59a12ed0 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -216,7 +216,7 @@ smbc_urlencode(char *dest, * are supported. */ -static const char *smbc_prefix = "smb:"; +#define SMBC_PREFIX "smb:" int SMBC_parse_path(TALLOC_CTX *ctx, @@ -263,8 +263,8 @@ SMBC_parse_path(TALLOC_CTX *ctx, s = talloc_strdup(ctx, fname); /* see if it has the right prefix */ - len = strlen(smbc_prefix); - if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { + len = strlen(SMBC_PREFIX); + if (strncmp(s,SMBC_PREFIX,len) || (s[len] != '/' && s[len] != 0)) { return -1; /* What about no smb: ? */ } -- cgit From 5a5af073bbc4a1bcb78cded8b45c646feeeb5d0d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 14 Feb 2009 13:43:09 +0100 Subject: Do not close an fd we know is -1 --- source3/smbd/server.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 28ce80b6c8..49995d8901 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -447,7 +447,6 @@ static bool smbd_open_one_socket(struct smbd_parent_context *parent, if (s->fd == -1) { DEBUG(0,("smbd_open_once_socket: open_socket_in: " "%s\n", strerror(errno))); - close(s->fd); TALLOC_FREE(s); /* * We ignore an error here, as we've done before -- cgit From e9467ff26ed429dbb2d4249da5bedf545664253b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 12 Feb 2009 16:21:45 +0100 Subject: Fix a typo --- source3/passdb/pdb_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 486b5b1b80..e618b425e0 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1947,7 +1947,7 @@ void pdb_search_destroy(struct pdb_search *search) } /******************************************************************* - trustodm methods + trustdom methods *******************************************************************/ bool pdb_get_trusteddom_pw(const char *domain, char** pwd, DOM_SID *sid, -- cgit From 4aed9abbf84deb47e7a3aec025268a3c1e6b29bb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 19 Feb 2009 23:41:48 +0100 Subject: Remove the static "chal" from ntlmssp.c:get_challenge() --- source3/auth/auth.c | 14 ++++++++------ source3/auth/auth_compat.c | 5 +++-- source3/auth/auth_ntlmssp.c | 6 ++++-- source3/include/auth.h | 3 ++- source3/include/ntlmssp.h | 3 ++- source3/libsmb/ntlmssp.c | 12 +++++------- source3/rpc_server/srv_netlog_nt.c | 4 ++-- source3/smbd/negprot.c | 5 ++--- source3/smbd/sesssetup.c | 7 ++++--- 9 files changed, 32 insertions(+), 27 deletions(-) diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 505098c76a..b19fa764f0 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -76,7 +76,8 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name Returns a const char of length 8 bytes. ****************************************************************************/ -static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) +static void get_ntlm_challenge(struct auth_context *auth_context, + uint8_t chal[8]) { DATA_BLOB challenge = data_blob_null; const char *challenge_set_by = NULL; @@ -86,7 +87,8 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) if (auth_context->challenge.length) { DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n", auth_context->challenge_set_by)); - return auth_context->challenge.data; + memcpy(chal, auth_context->challenge.data, 8); + return; } auth_context->challenge_may_be_modified = False; @@ -123,11 +125,11 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) } if (!challenge_set_by) { - uchar chal[8]; + uchar tmp[8]; - generate_random_buffer(chal, sizeof(chal)); + generate_random_buffer(tmp, sizeof(tmp)); auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, - chal, sizeof(chal)); + tmp, sizeof(tmp)); challenge_set_by = "random"; auth_context->challenge_may_be_modified = True; @@ -141,7 +143,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) auth_context->challenge_set_by=challenge_set_by; - return auth_context->challenge.data; + memcpy(chal, auth_context->challenge.data, 8); } diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c index 00d9dea816..925c0d4f81 100644 --- a/source3/auth/auth_compat.c +++ b/source3/auth/auth_compat.c @@ -39,13 +39,14 @@ NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_pass { struct auth_context *plaintext_auth_context = NULL; auth_usersupplied_info *user_info = NULL; - const uint8 *chal; + uint8_t chal[8]; NTSTATUS nt_status; if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) { return nt_status; } - chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context); + plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context, + chal); if (!make_user_info_for_reply(&user_info, smb_name, lp_workgroup(), chal, diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index 0d46b14f97..98f5838707 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -27,11 +27,13 @@ * @return an 8 byte random challenge */ -static const uint8 *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state) +static void auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state, + uint8_t chal[8]) { AUTH_NTLMSSP_STATE *auth_ntlmssp_state = (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context; - return auth_ntlmssp_state->auth_context->get_ntlm_challenge(auth_ntlmssp_state->auth_context); + return auth_ntlmssp_state->auth_context->get_ntlm_challenge( + auth_ntlmssp_state->auth_context, chal); } /** diff --git a/source3/include/auth.h b/source3/include/auth.h index 17bccce3d7..7d778b92d0 100644 --- a/source3/include/auth.h +++ b/source3/include/auth.h @@ -92,7 +92,8 @@ struct auth_context { struct auth_methods *auth_method_list; TALLOC_CTX *mem_ctx; - const uint8 *(*get_ntlm_challenge)(struct auth_context *auth_context); + void (*get_ntlm_challenge)(struct auth_context *auth_context, + uint8_t chal[8]); NTSTATUS (*check_ntlm_password)(const struct auth_context *auth_context, const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **server_info); diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h index 55b9249ea7..f3414fe928 100644 --- a/source3/include/ntlmssp.h +++ b/source3/include/ntlmssp.h @@ -109,7 +109,8 @@ typedef struct ntlmssp_state * @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication * */ - const uint8 *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state); + void (*get_challenge)(const struct ntlmssp_state *ntlmssp_state, + uint8_t challenge[8]); /** * Callback to find if the challenge used by NTLM authentication may be modified diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index cc13476935..0764f97d85 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -110,12 +110,10 @@ void debug_ntlmssp_flags(uint32 neg_flags) * */ -static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state) +static void get_challenge(const struct ntlmssp_state *ntlmssp_state, + uint8_t chal[8]) { - static uchar chal[8]; - generate_random_buffer(chal, sizeof(chal)); - - return chal; + generate_random_buffer(chal, 8); } /** @@ -517,7 +515,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, char *dnsdomname = NULL; uint32 neg_flags = 0; uint32 ntlmssp_command, chal_flags; - const uint8 *cryptkey; + uint8_t cryptkey[8]; const char *target_name; /* parse the NTLMSSP packet */ @@ -541,7 +539,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); /* Ask our caller what challenge they would like in the packet */ - cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); + ntlmssp_state->get_challenge(ntlmssp_state, cryptkey); /* Check if we may set the challenge */ if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) { diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index a38c717665..0c83144a90 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -990,13 +990,13 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p, this to challenge/response for the auth subsystem to chew on */ { - const uint8 *chal; + uint8_t chal[8]; if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) { return status; } - chal = auth_context->get_ntlm_challenge(auth_context); + auth_context->get_ntlm_challenge(auth_context, chal); if (!make_user_info_netlogon_interactive(&user_info, nt_username, nt_domain, diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 57608a9b40..a921954c49 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -27,7 +27,6 @@ extern enum protocol_types Protocol; static void get_challenge(uint8 buff[8]) { NTSTATUS nt_status; - const uint8 *cryptkey; /* We might be called more than once, multiple negprots are * permitted */ @@ -42,8 +41,8 @@ static void get_challenge(uint8 buff[8]) smb_panic("cannot make_negprot_global_auth_context!"); } DEBUG(10, ("get challenge: getting challenge\n")); - cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context); - memcpy(buff, cryptkey, 8); + negprot_global_auth_context->get_ntlm_challenge( + negprot_global_auth_context, buff); } /**************************************************************************** diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7a03ef7f3c..8a09ed39a9 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1691,14 +1691,15 @@ void reply_sesssetup_and_X(struct smb_request *req) } } else { struct auth_context *plaintext_auth_context = NULL; - const uint8 *chal; nt_status = make_auth_context_subsystem( &plaintext_auth_context); if (NT_STATUS_IS_OK(nt_status)) { - chal = plaintext_auth_context->get_ntlm_challenge( - plaintext_auth_context); + uint8_t chal[8]; + + plaintext_auth_context->get_ntlm_challenge( + plaintext_auth_context, chal); if (!make_user_info_for_reply(&user_info, user, domain, chal, -- cgit From a3127ea9d7197af8ddde3f8e20a92794f389a992 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Feb 2009 13:20:08 +0100 Subject: Fix some nonempty blank lines --- source3/auth/auth.c | 62 ++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/source3/auth/auth.c b/source3/auth/auth.c index b19fa764f0..fd4c503752 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -2,17 +2,17 @@ Unix SMB/CIFS implementation. Password and authentication handling Copyright (C) Andrew Bartlett 2001-2002 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -49,7 +49,7 @@ NTSTATUS smb_register_auth(int version, const char *name, auth_init_function ini DEBUG(0,("There already is an auth method registered with the name %s!\n", name)); return NT_STATUS_OBJECT_NAME_COLLISION; } - + entry = SMB_XMALLOC_P(struct auth_init_function_entry); entry->name = smb_xstrdup(name); entry->init = init; @@ -67,7 +67,7 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name if (strcmp(entry->name, name)==0) return entry; entry = entry->next; } - + return NULL; } @@ -110,7 +110,7 @@ static void get_ntlm_challenge(struct auth_context *auth_context, if (!mem_ctx) { smb_panic("talloc_init() failed!"); } - + challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx); if (!challenge.length) { DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n", @@ -123,22 +123,22 @@ static void get_ntlm_challenge(struct auth_context *auth_context, } talloc_destroy(mem_ctx); } - + if (!challenge_set_by) { uchar tmp[8]; - + generate_random_buffer(tmp, sizeof(tmp)); auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, tmp, sizeof(tmp)); - + challenge_set_by = "random"; auth_context->challenge_may_be_modified = True; } - + DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by)); DEBUG(5, ("challenge is: \n")); dump_data(5, auth_context->challenge.data, auth_context->challenge.length); - + SMB_ASSERT(auth_context->challenge.length == 8); auth_context->challenge_set_by=challenge_set_by; @@ -251,7 +251,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) { NTSTATUS result; - + mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name, user_info->domain, user_info->smb_name); @@ -283,7 +283,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, } /* successful authentication */ - + if (NT_STATUS_IS_OK(nt_status)) { unix_username = (*server_info)->unix_name; if (!(*server_info)->guest) { @@ -291,7 +291,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, become_root(); nt_status = smb_pam_accountcheck(unix_username); unbecome_root(); - + if (NT_STATUS_IS_OK(nt_status)) { DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] succeeded\n", unix_username)); @@ -300,7 +300,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, unix_username, nt_errstr(nt_status))); } } - + if (NT_STATUS_IS_OK(nt_status)) { DEBUG((*server_info)->guest ? 5 : 2, ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n", @@ -309,17 +309,17 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, user_info->internal_username, unix_username)); } - + return nt_status; } - + /* failed authentication; check for guest lapping */ - + DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n", user_info->smb_name, user_info->internal_username, nt_errstr(nt_status))); ZERO_STRUCTP(server_info); - + return nt_status; } @@ -351,7 +351,7 @@ static NTSTATUS make_auth_context(struct auth_context **auth_context) TALLOC_CTX *mem_ctx; mem_ctx = talloc_init("authentication context"); - + *auth_context = TALLOC_P(mem_ctx, struct auth_context); if (!*auth_context) { DEBUG(0,("make_auth_context: talloc failed!\n")); @@ -364,7 +364,7 @@ static NTSTATUS make_auth_context(struct auth_context **auth_context) (*auth_context)->check_ntlm_password = check_ntlm_password; (*auth_context)->get_ntlm_challenge = get_ntlm_challenge; (*auth_context)->free = free_auth_context; - + return NT_STATUS_OK; } @@ -384,21 +384,21 @@ bool load_auth_module(struct auth_context *auth_context, static_init_auth; initialised_static_modules = True; } - + DEBUG(5,("load_auth_module: Attempting to find an auth method to match %s\n", module)); - + p = strchr(module_name, ':'); if (p) { *p = 0; module_params = p+1; trim_char(module_params, ' ', ' '); } - + trim_char(module_name, ' ', ' '); - + entry = auth_find_backend_entry(module_name); - + if (entry == NULL) { if (NT_STATUS_IS_OK(smb_probe_module("auth", module_name))) { entry = auth_find_backend_entry(module_name); @@ -436,7 +436,7 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, DEBUG(2,("make_auth_context_text_list: No auth method list!?\n")); return NT_STATUS_UNSUCCESSFUL; } - + if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context))) return nt_status; @@ -445,9 +445,9 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, DLIST_ADD_END(list, t, auth_methods *); } } - + (*auth_context)->auth_method_list = list; - + return nt_status; } @@ -525,7 +525,7 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) } else { DEBUG(5,("Using specified auth order\n")); } - + nt_status = make_auth_context_text_list(auth_context, auth_method_list); @@ -543,7 +543,7 @@ NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[ if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) { return nt_status; } - + (*auth_context)->challenge = data_blob_talloc((*auth_context)->mem_ctx, chal, 8); (*auth_context)->challenge_set_by = "fixed"; return nt_status; -- cgit From fb1c564b78032b61bba182e748cdbadf94d26e15 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 21 Feb 2009 18:21:20 +0100 Subject: Add --enable-external-* flags for libraries shipped with Samba, to allow explicitly enabling or disabling the use of the version provided by the system. --- source4/build/m4/public.m4 | 22 ++++++++++++++++++++++ source4/configure.ac | 9 ++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index 1823f1ba97..a707a113cd 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -6,6 +6,8 @@ dnl Published under the GPL dnl dnl SMB_EXT_LIB_FROM_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) dnl +dnl SMB_INCLUDED_LIB_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) +dnl dnl SMB_EXT_LIB(name,libs,cflags,cppflags,ldflags) dnl dnl SMB_ENABLE(name,default_build) @@ -125,6 +127,26 @@ AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG], fi ]) +dnl SMB_INCLUDED_LIB_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) +AC_DEFUN([SMB_INCLUDED_LIB_PKGCONFIG], +[ + AC_ARG_ENABLE([external-]translit($1,`A-Z',`a-z'), + AS_HELP_STRING([--enable-external-]translit($1,`A-Z',`a-z'), [Use external $1 instead of built-in (default=auto)]), [], [enableval=auto]) + + if test $enableval = yes -o $enableval = auto; then + SMB_EXT_LIB_FROM_PKGCONFIG([$1], [$2], [$3], [ + if test $enableval = yes; then + AC_MSG_ERROR([Unable to find external $1]) + fi + ]) + else + ifelse([$4], [], [ + SMB_EXT_LIB($1) + SMB_ENABLE($1, NO) + ], [$4]) + fi +]) + dnl SMB_INCLUDE_MK(file) AC_DEFUN([SMB_INCLUDE_MK], [ diff --git a/source4/configure.ac b/source4/configure.ac index 85ea44f570..bc3c01173f 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -42,15 +42,14 @@ AC_CONFIG_FILES(param/samba-hostconfig.pc) AC_CONFIG_FILES(librpc/dcerpc_samr.pc) AC_CONFIG_FILES(librpc/dcerpc_atsvc.pc) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0, - [], +SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0, [], [ m4_include(../lib/talloc/libtalloc.m4) SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3, +SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= 1.1.3, [], [ m4_include(../lib/tdb/libtdb.m4) @@ -60,13 +59,13 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3, SMB_INCLUDE_MK(../lib/tdb/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = 0.9.3, +SMB_INCLUDED_LIB_PKGCONFIG(LIBTEVENT, tevent = 0.9.3, [],[m4_include(../lib/tevent/samba.m4)] ) SMB_INCLUDE_MK(../lib/tevent/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = 0.9.3, +SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = 0.9.3, [ SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk) SMB_INCLUDE_MK(lib/ldb/tools/config.mk) -- cgit From 4a2e2c0c12e298cb72d4c03e59350393b0a5814f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Feb 2009 18:55:35 +0100 Subject: Fix the build on Solaris --- source3/auth/auth_ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index 98f5838707..034d354a33 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -32,7 +32,7 @@ static void auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state { AUTH_NTLMSSP_STATE *auth_ntlmssp_state = (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context; - return auth_ntlmssp_state->auth_context->get_ntlm_challenge( + auth_ntlmssp_state->auth_context->get_ntlm_challenge( auth_ntlmssp_state->auth_context, chal); } -- cgit From 80e9e63cf611ed45cb2bfb4896f962270e92ee8e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 21 Feb 2009 18:59:12 +0100 Subject: Let --enable-external-libldb default to no (since linking against external LDB doesn't work yet). Fix flags when using internal libs. --- source4/build/m4/public.m4 | 6 ++++-- source4/configure.ac | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index a707a113cd..1927e9977f 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -131,15 +131,17 @@ dnl SMB_INCLUDED_LIB_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF AC_DEFUN([SMB_INCLUDED_LIB_PKGCONFIG], [ AC_ARG_ENABLE([external-]translit($1,`A-Z',`a-z'), - AS_HELP_STRING([--enable-external-]translit($1,`A-Z',`a-z'), [Use external $1 instead of built-in (default=auto)]), [], [enableval=auto]) + AS_HELP_STRING([--enable-external-]translit($1,`A-Z',`a-z'), [Use external $1 instead of built-in (default=ifelse([$5],[],auto,$5))]), [], [enableval=ifelse([$5],[],auto,$5)]) if test $enableval = yes -o $enableval = auto; then SMB_EXT_LIB_FROM_PKGCONFIG([$1], [$2], [$3], [ if test $enableval = yes; then AC_MSG_ERROR([Unable to find external $1]) fi + enableval=no ]) - else + fi + if test $enableval = no; then ifelse([$4], [], [ SMB_EXT_LIB($1) SMB_ENABLE($1, NO) diff --git a/source4/configure.ac b/source4/configure.ac index bc3c01173f..54ca9108b1 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -95,8 +95,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = 0.9.3, m4_include(lib/ldb/libldb.m4) SMB_INCLUDE_MK(lib/ldb/config.mk) AC_CONFIG_FILES(lib/ldb/ldb.pc) - ] -) + ], [no]) SMB_INCLUDE_MK(lib/ldb/python.mk) m4_include(lib/tls/config.m4) -- cgit From c9a057bc0497fd201142799d02f046e95236f921 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 21 Feb 2009 19:08:24 +0100 Subject: pytevent: Fix include path - tevent_util is not installed. --- lib/tevent/pytevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c index 4c0cbfd3cd..3b45ba1928 100644 --- a/lib/tevent/pytevent.c +++ b/lib/tevent/pytevent.c @@ -29,7 +29,7 @@ #include #include -#include +#include "tevent_util.h" typedef struct { PyObject_HEAD -- cgit From 80cd7ed51998daea5233ce17a72ae470d438425c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Feb 2009 14:18:06 +0100 Subject: eventlog: fix eventlog_GetLogInformation typo in IDL. Guenther --- librpc/idl/eventlog.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index c7524f3c38..aba294828b 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -314,7 +314,7 @@ import "lsa.idl", "security.idl"; boolean32 full; } EVENTLOG_FULL_INFORMATION; - NTSTATUS eventlog_GetLogIntormation( + NTSTATUS eventlog_GetLogInformation( [in] policy_handle *handle, [in] uint32 level, [out,ref] [size_is(buf_size)] uint8 *buffer, -- cgit From dc8ab10d3d321e8389391f485d6ed177534de2cb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Feb 2009 14:20:05 +0100 Subject: eventlog: remove unused eventlog_Record struct. Guenther --- librpc/idl/eventlog.idl | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index aba294828b..6b46acec7d 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -31,32 +31,6 @@ import "lsa.idl", "security.idl"; uint16 unknown0; uint16 unknown1; } eventlog_OpenUnknown0; - - typedef [flag(NDR_NOALIGN),public] struct { - uint32 size; - [charset(DOS),value("eLfL")] uint8 reserved[4]; - uint32 record_number; - time_t time_generated; - time_t time_written; - uint32 event_id; - eventlogEventTypes event_type; - [range(0,256)] uint16 num_of_strings; - uint16 event_category; - uint16 reserved_flags; - uint32 closing_record_number; - uint32 stringoffset; - [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size; - uint32 sid_offset; - uint32 data_length; - uint32 data_offset; - nstring source_name; - nstring computer_name; - [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid; - nstring strings[num_of_strings]; - astring raw_data; - [flag(NDR_ALIGN4)] DATA_BLOB _padding; - [value(size)] uint32 size2; - } eventlog_Record; /* compat structure for samba3 on-disc eventlog format, this is *NOT* used on the wire. - gd */ -- cgit From acfa1278ae6611783f9a13e54ac78c10bc828b9f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 21 Feb 2009 21:03:13 +0100 Subject: spoolss: add spoolssNotifyOptionFlags. Guenther --- librpc/idl/spoolss.idl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 4bb68fac00..b441f17cf1 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1644,9 +1644,13 @@ import "misc.idl", "security.idl", "winreg.idl"; [size_is(count)] spoolss_Field *fields; } spoolss_NotifyOptionType; + typedef [bitmap32bit] bitmap { + PRINTER_NOTIFY_OPTIONS_REFRESH = 0x00000001 + } spoolssNotifyOptionFlags; + typedef struct { [value(2)] uint32 version; - uint32 flags; + spoolssNotifyOptionFlags flags; uint32 count; [size_is(count)] spoolss_NotifyOptionType *types; } spoolss_NotifyOption; -- cgit From 3bd612527d9c25ee5a7f33fce0ba2902bb15a4d6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 21 Feb 2009 21:13:46 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/cli_eventlog.c | 10 +- librpc/gen_ndr/cli_eventlog.h | 2 +- librpc/gen_ndr/eventlog.h | 28 +----- librpc/gen_ndr/ndr_eventlog.c | 217 +++--------------------------------------- librpc/gen_ndr/ndr_eventlog.h | 7 +- librpc/gen_ndr/ndr_spoolss.c | 28 +++++- librpc/gen_ndr/ndr_spoolss.h | 1 + librpc/gen_ndr/spoolss.h | 3 + librpc/gen_ndr/srv_eventlog.c | 22 ++--- librpc/gen_ndr/srv_eventlog.h | 4 +- 10 files changed, 62 insertions(+), 260 deletions(-) diff --git a/librpc/gen_ndr/cli_eventlog.c b/librpc/gen_ndr/cli_eventlog.c index 6b084d2217..b9cf39dea0 100644 --- a/librpc/gen_ndr/cli_eventlog.c +++ b/librpc/gen_ndr/cli_eventlog.c @@ -902,7 +902,7 @@ NTSTATUS rpccli_eventlog_WriteClusterEvents(struct rpc_pipe_client *cli, return r.out.result; } -NTSTATUS rpccli_eventlog_GetLogIntormation(struct rpc_pipe_client *cli, +NTSTATUS rpccli_eventlog_GetLogInformation(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t level /* [in] */, @@ -910,7 +910,7 @@ NTSTATUS rpccli_eventlog_GetLogIntormation(struct rpc_pipe_client *cli, uint32_t buf_size /* [in] [range(0,1024)] */, uint32_t *bytes_needed /* [out] [ref] */) { - struct eventlog_GetLogIntormation r; + struct eventlog_GetLogInformation r; NTSTATUS status; /* In parameters */ @@ -919,13 +919,13 @@ NTSTATUS rpccli_eventlog_GetLogIntormation(struct rpc_pipe_client *cli, r.in.buf_size = buf_size; if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(eventlog_GetLogIntormation, &r); + NDR_PRINT_IN_DEBUG(eventlog_GetLogInformation, &r); } status = cli->dispatch(cli, mem_ctx, &ndr_table_eventlog, - NDR_EVENTLOG_GETLOGINTORMATION, + NDR_EVENTLOG_GETLOGINFORMATION, &r); if (!NT_STATUS_IS_OK(status)) { @@ -933,7 +933,7 @@ NTSTATUS rpccli_eventlog_GetLogIntormation(struct rpc_pipe_client *cli, } if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(eventlog_GetLogIntormation, &r); + NDR_PRINT_OUT_DEBUG(eventlog_GetLogInformation, &r); } if (NT_STATUS_IS_ERR(status)) { diff --git a/librpc/gen_ndr/cli_eventlog.h b/librpc/gen_ndr/cli_eventlog.h index ae5544daf3..d905676041 100644 --- a/librpc/gen_ndr/cli_eventlog.h +++ b/librpc/gen_ndr/cli_eventlog.h @@ -93,7 +93,7 @@ NTSTATUS rpccli_eventlog_DeregisterClusterSvc(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx); NTSTATUS rpccli_eventlog_WriteClusterEvents(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx); -NTSTATUS rpccli_eventlog_GetLogIntormation(struct rpc_pipe_client *cli, +NTSTATUS rpccli_eventlog_GetLogInformation(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t level /* [in] */, diff --git a/librpc/gen_ndr/eventlog.h b/librpc/gen_ndr/eventlog.h index 94da688f5c..2a9b824601 100644 --- a/librpc/gen_ndr/eventlog.h +++ b/librpc/gen_ndr/eventlog.h @@ -39,32 +39,6 @@ struct eventlog_OpenUnknown0 { uint16_t unknown1; }; -struct eventlog_Record { - uint32_t size; - const char *reserved;/* [value("eLfL"),charset(DOS)] */ - uint32_t record_number; - time_t time_generated; - time_t time_written; - uint32_t event_id; - enum eventlogEventTypes event_type; - uint16_t num_of_strings;/* [range(0,256)] */ - uint16_t event_category; - uint16_t reserved_flags; - uint32_t closing_record_number; - uint32_t stringoffset; - uint32_t sid_size;/* [value(ndr_size_dom_sid0(&sid,ndr->flags))] */ - uint32_t sid_offset; - uint32_t data_length; - uint32_t data_offset; - const char * source_name;/* [flag(LIBNDR_FLAG_STR_NULLTERM)] */ - const char * computer_name;/* [flag(LIBNDR_FLAG_STR_NULLTERM)] */ - struct dom_sid0 sid;/* [subcontext_size(sid_size),subcontext(0)] */ - const char * *strings;/* [flag(LIBNDR_FLAG_STR_NULLTERM)] */ - const char * raw_data;/* [flag(LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM)] */ - DATA_BLOB _padding;/* [flag(LIBNDR_FLAG_ALIGN4)] */ - uint32_t size2;/* [value(size)] */ -}/* [public,flag(LIBNDR_FLAG_NOALIGN)] */; - struct eventlog_Record_tdb { uint32_t size; const char *reserved;/* [value("eLfL"),charset(DOS)] */ @@ -437,7 +411,7 @@ struct eventlog_WriteClusterEvents { }; -struct eventlog_GetLogIntormation { +struct eventlog_GetLogInformation { struct { struct policy_handle *handle;/* [ref] */ uint32_t level; diff --git a/librpc/gen_ndr/ndr_eventlog.c b/librpc/gen_ndr/ndr_eventlog.c index 0d5654c640..3f19902690 100644 --- a/librpc/gen_ndr/ndr_eventlog.c +++ b/librpc/gen_ndr/ndr_eventlog.c @@ -92,201 +92,6 @@ _PUBLIC_ void ndr_print_eventlog_OpenUnknown0(struct ndr_print *ndr, const char ndr->depth--; } -_PUBLIC_ enum ndr_err_code ndr_push_eventlog_Record(struct ndr_push *ndr, int ndr_flags, const struct eventlog_Record *r) -{ - uint32_t cntr_strings_0; - { - uint32_t _flags_save_STRUCT = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size)); - NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, "eLfL", 4, sizeof(uint8_t), CH_DOS)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->record_number)); - NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, r->time_generated)); - NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, r->time_written)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->event_id)); - NDR_CHECK(ndr_push_eventlogEventTypes(ndr, NDR_SCALARS, r->event_type)); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->num_of_strings)); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->event_category)); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->reserved_flags)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->closing_record_number)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->stringoffset)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_dom_sid0(&r->sid, ndr->flags))); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sid_offset)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->data_length)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->data_offset)); - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); - NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->source_name)); - ndr->flags = _flags_save_string; - } - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); - NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->computer_name)); - ndr->flags = _flags_save_string; - } - { - struct ndr_push *_ndr_sid; - NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags))); - NDR_CHECK(ndr_push_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid)); - NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags))); - } - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); - for (cntr_strings_0 = 0; cntr_strings_0 < r->num_of_strings; cntr_strings_0++) { - NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->strings[cntr_strings_0])); - } - ndr->flags = _flags_save_string; - } - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); - NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->raw_data)); - ndr->flags = _flags_save_string; - } - { - uint32_t _flags_save_DATA_BLOB = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); - NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_padding)); - ndr->flags = _flags_save_DATA_BLOB; - } - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size)); - } - if (ndr_flags & NDR_BUFFERS) { - } - ndr->flags = _flags_save_STRUCT; - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ enum ndr_err_code ndr_pull_eventlog_Record(struct ndr_pull *ndr, int ndr_flags, struct eventlog_Record *r) -{ - uint32_t cntr_strings_0; - TALLOC_CTX *_mem_save_strings_0; - { - uint32_t _flags_save_STRUCT = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size)); - NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->reserved, 4, sizeof(uint8_t), CH_DOS)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->record_number)); - NDR_CHECK(ndr_pull_time_t(ndr, NDR_SCALARS, &r->time_generated)); - NDR_CHECK(ndr_pull_time_t(ndr, NDR_SCALARS, &r->time_written)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->event_id)); - NDR_CHECK(ndr_pull_eventlogEventTypes(ndr, NDR_SCALARS, &r->event_type)); - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->num_of_strings)); - if (r->num_of_strings > 256) { - return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); - } - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->event_category)); - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->reserved_flags)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->closing_record_number)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->stringoffset)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sid_size)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sid_offset)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->data_length)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->data_offset)); - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); - NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->source_name)); - ndr->flags = _flags_save_string; - } - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); - NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->computer_name)); - ndr->flags = _flags_save_string; - } - { - struct ndr_pull *_ndr_sid; - NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sid, 0, r->sid_size)); - NDR_CHECK(ndr_pull_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid)); - NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sid, 0, r->sid_size)); - } - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); - NDR_PULL_ALLOC_N(ndr, r->strings, r->num_of_strings); - _mem_save_strings_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->strings, 0); - for (cntr_strings_0 = 0; cntr_strings_0 < r->num_of_strings; cntr_strings_0++) { - NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->strings[cntr_strings_0])); - } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_strings_0, 0); - ndr->flags = _flags_save_string; - } - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); - NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->raw_data)); - ndr->flags = _flags_save_string; - } - { - uint32_t _flags_save_DATA_BLOB = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); - NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_padding)); - ndr->flags = _flags_save_DATA_BLOB; - } - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size2)); - } - if (ndr_flags & NDR_BUFFERS) { - } - ndr->flags = _flags_save_STRUCT; - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_eventlog_Record(struct ndr_print *ndr, const char *name, const struct eventlog_Record *r) -{ - uint32_t cntr_strings_0; - ndr_print_struct(ndr, name, "eventlog_Record"); - { - uint32_t _flags_save_STRUCT = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); - ndr->depth++; - ndr_print_uint32(ndr, "size", r->size); - ndr_print_string(ndr, "reserved", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?"eLfL":r->reserved); - ndr_print_uint32(ndr, "record_number", r->record_number); - ndr_print_time_t(ndr, "time_generated", r->time_generated); - ndr_print_time_t(ndr, "time_written", r->time_written); - ndr_print_uint32(ndr, "event_id", r->event_id); - ndr_print_eventlogEventTypes(ndr, "event_type", r->event_type); - ndr_print_uint16(ndr, "num_of_strings", r->num_of_strings); - ndr_print_uint16(ndr, "event_category", r->event_category); - ndr_print_uint16(ndr, "reserved_flags", r->reserved_flags); - ndr_print_uint32(ndr, "closing_record_number", r->closing_record_number); - ndr_print_uint32(ndr, "stringoffset", r->stringoffset); - ndr_print_uint32(ndr, "sid_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_dom_sid0(&r->sid, ndr->flags):r->sid_size); - ndr_print_uint32(ndr, "sid_offset", r->sid_offset); - ndr_print_uint32(ndr, "data_length", r->data_length); - ndr_print_uint32(ndr, "data_offset", r->data_offset); - ndr_print_string(ndr, "source_name", r->source_name); - ndr_print_string(ndr, "computer_name", r->computer_name); - ndr_print_dom_sid0(ndr, "sid", &r->sid); - ndr->print(ndr, "%s: ARRAY(%d)", "strings", (int)r->num_of_strings); - ndr->depth++; - for (cntr_strings_0=0;cntr_strings_0num_of_strings;cntr_strings_0++) { - char *idx_0=NULL; - if (asprintf(&idx_0, "[%d]", cntr_strings_0) != -1) { - ndr_print_string(ndr, "strings", r->strings[cntr_strings_0]); - free(idx_0); - } - } - ndr->depth--; - ndr_print_string(ndr, "raw_data", r->raw_data); - ndr_print_DATA_BLOB(ndr, "_padding", r->_padding); - ndr_print_uint32(ndr, "size2", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?r->size:r->size2); - ndr->depth--; - ndr->flags = _flags_save_STRUCT; - } -} - _PUBLIC_ enum ndr_err_code ndr_push_eventlog_Record_tdb(struct ndr_push *ndr, int ndr_flags, const struct eventlog_Record_tdb *r) { uint32_t cntr_strings_0; @@ -2589,7 +2394,7 @@ _PUBLIC_ void ndr_print_eventlog_WriteClusterEvents(struct ndr_print *ndr, const ndr->depth--; } -static enum ndr_err_code ndr_push_eventlog_GetLogIntormation(struct ndr_push *ndr, int flags, const struct eventlog_GetLogIntormation *r) +static enum ndr_err_code ndr_push_eventlog_GetLogInformation(struct ndr_push *ndr, int flags, const struct eventlog_GetLogInformation *r) { if (flags & NDR_IN) { if (r->in.handle == NULL) { @@ -2614,7 +2419,7 @@ static enum ndr_err_code ndr_push_eventlog_GetLogIntormation(struct ndr_push *nd return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_eventlog_GetLogIntormation(struct ndr_pull *ndr, int flags, struct eventlog_GetLogIntormation *r) +static enum ndr_err_code ndr_pull_eventlog_GetLogInformation(struct ndr_pull *ndr, int flags, struct eventlog_GetLogInformation *r) { TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_bytes_needed_0; @@ -2659,15 +2464,15 @@ static enum ndr_err_code ndr_pull_eventlog_GetLogIntormation(struct ndr_pull *nd return NDR_ERR_SUCCESS; } -_PUBLIC_ void ndr_print_eventlog_GetLogIntormation(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_GetLogIntormation *r) +_PUBLIC_ void ndr_print_eventlog_GetLogInformation(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_GetLogInformation *r) { - ndr_print_struct(ndr, name, "eventlog_GetLogIntormation"); + ndr_print_struct(ndr, name, "eventlog_GetLogInformation"); ndr->depth++; if (flags & NDR_SET_VALUES) { ndr->flags |= LIBNDR_PRINT_SET_VALUES; } if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "eventlog_GetLogIntormation"); + ndr_print_struct(ndr, "in", "eventlog_GetLogInformation"); ndr->depth++; ndr_print_ptr(ndr, "handle", r->in.handle); ndr->depth++; @@ -2678,7 +2483,7 @@ _PUBLIC_ void ndr_print_eventlog_GetLogIntormation(struct ndr_print *ndr, const ndr->depth--; } if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "eventlog_GetLogIntormation"); + ndr_print_struct(ndr, "out", "eventlog_GetLogInformation"); ndr->depth++; ndr_print_ptr(ndr, "buffer", r->out.buffer); ndr->depth++; @@ -3267,11 +3072,11 @@ static const struct ndr_interface_call eventlog_calls[] = { false, }, { - "eventlog_GetLogIntormation", - sizeof(struct eventlog_GetLogIntormation), - (ndr_push_flags_fn_t) ndr_push_eventlog_GetLogIntormation, - (ndr_pull_flags_fn_t) ndr_pull_eventlog_GetLogIntormation, - (ndr_print_function_t) ndr_print_eventlog_GetLogIntormation, + "eventlog_GetLogInformation", + sizeof(struct eventlog_GetLogInformation), + (ndr_push_flags_fn_t) ndr_push_eventlog_GetLogInformation, + (ndr_pull_flags_fn_t) ndr_pull_eventlog_GetLogInformation, + (ndr_print_function_t) ndr_print_eventlog_GetLogInformation, false, }, { diff --git a/librpc/gen_ndr/ndr_eventlog.h b/librpc/gen_ndr/ndr_eventlog.h index 34e6e09637..39f5f1bbc8 100644 --- a/librpc/gen_ndr/ndr_eventlog.h +++ b/librpc/gen_ndr/ndr_eventlog.h @@ -55,7 +55,7 @@ extern const struct ndr_interface_table ndr_table_eventlog; #define NDR_EVENTLOG_WRITECLUSTEREVENTS (0x15) -#define NDR_EVENTLOG_GETLOGINTORMATION (0x16) +#define NDR_EVENTLOG_GETLOGINFORMATION (0x16) #define NDR_EVENTLOG_FLUSHEVENTLOG (0x17) @@ -67,9 +67,6 @@ enum ndr_err_code ndr_push_eventlogEventTypes(struct ndr_push *ndr, int ndr_flag enum ndr_err_code ndr_pull_eventlogEventTypes(struct ndr_pull *ndr, int ndr_flags, enum eventlogEventTypes *r); void ndr_print_eventlogEventTypes(struct ndr_print *ndr, const char *name, enum eventlogEventTypes r); void ndr_print_eventlog_OpenUnknown0(struct ndr_print *ndr, const char *name, const struct eventlog_OpenUnknown0 *r); -enum ndr_err_code ndr_push_eventlog_Record(struct ndr_push *ndr, int ndr_flags, const struct eventlog_Record *r); -enum ndr_err_code ndr_pull_eventlog_Record(struct ndr_pull *ndr, int ndr_flags, struct eventlog_Record *r); -void ndr_print_eventlog_Record(struct ndr_print *ndr, const char *name, const struct eventlog_Record *r); enum ndr_err_code ndr_push_eventlog_Record_tdb(struct ndr_push *ndr, int ndr_flags, const struct eventlog_Record_tdb *r); enum ndr_err_code ndr_pull_eventlog_Record_tdb(struct ndr_pull *ndr, int ndr_flags, struct eventlog_Record_tdb *r); void ndr_print_eventlog_Record_tdb(struct ndr_print *ndr, const char *name, const struct eventlog_Record_tdb *r); @@ -109,7 +106,7 @@ void ndr_print_eventlog_ReportEventA(struct ndr_print *ndr, const char *name, in void ndr_print_eventlog_RegisterClusterSvc(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_RegisterClusterSvc *r); void ndr_print_eventlog_DeregisterClusterSvc(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_DeregisterClusterSvc *r); void ndr_print_eventlog_WriteClusterEvents(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_WriteClusterEvents *r); -void ndr_print_eventlog_GetLogIntormation(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_GetLogIntormation *r); +void ndr_print_eventlog_GetLogInformation(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_GetLogInformation *r); void ndr_print_eventlog_FlushEventLog(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_FlushEventLog *r); void ndr_print_eventlog_ReportEventAndSourceW(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_ReportEventAndSourceW *r); #endif /* _HEADER_NDR_eventlog */ diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 9ec3f35930..b0d5366636 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -13226,13 +13226,35 @@ _PUBLIC_ void ndr_print_spoolss_NotifyOptionType(struct ndr_print *ndr, const ch ndr->depth--; } +static enum ndr_err_code ndr_push_spoolssNotifyOptionFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolssNotifyOptionFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolssNotifyOptionFlags(struct ndr_print *ndr, const char *name, uint32_t r) +{ + ndr_print_uint32(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_NOTIFY_OPTIONS_REFRESH", PRINTER_NOTIFY_OPTIONS_REFRESH, r); + ndr->depth--; +} + static enum ndr_err_code ndr_push_spoolss_NotifyOption(struct ndr_push *ndr, int ndr_flags, const struct spoolss_NotifyOption *r) { uint32_t cntr_types_1; if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 2)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->flags)); + NDR_CHECK(ndr_push_spoolssNotifyOptionFlags(ndr, NDR_SCALARS, r->flags)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->types)); } @@ -13259,7 +13281,7 @@ static enum ndr_err_code ndr_pull_spoolss_NotifyOption(struct ndr_pull *ndr, int if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->flags)); + NDR_CHECK(ndr_pull_spoolssNotifyOptionFlags(ndr, NDR_SCALARS, &r->flags)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_types)); if (_ptr_types) { @@ -13298,7 +13320,7 @@ _PUBLIC_ void ndr_print_spoolss_NotifyOption(struct ndr_print *ndr, const char * ndr_print_struct(ndr, name, "spoolss_NotifyOption"); ndr->depth++; ndr_print_uint32(ndr, "version", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->version); - ndr_print_uint32(ndr, "flags", r->flags); + ndr_print_spoolssNotifyOptionFlags(ndr, "flags", r->flags); ndr_print_uint32(ndr, "count", r->count); ndr_print_ptr(ndr, "types", r->types); ndr->depth++; diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index f8d97c19a7..b9a533ab38 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -334,6 +334,7 @@ void ndr_print_spoolss_PrinterChangeFlags(struct ndr_print *ndr, const char *nam void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, enum spoolss_Field r); void ndr_print_spoolss_NotifyType(struct ndr_print *ndr, const char *name, enum spoolss_NotifyType r); void ndr_print_spoolss_NotifyOptionType(struct ndr_print *ndr, const char *name, const struct spoolss_NotifyOptionType *r); +void ndr_print_spoolssNotifyOptionFlags(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_spoolss_NotifyOption(struct ndr_print *ndr, const char *name, const struct spoolss_NotifyOption *r); void ndr_print_spoolss_NotifyString(struct ndr_print *ndr, const char *name, const struct spoolss_NotifyString *r); void ndr_print_spoolss_NotifyTable(struct ndr_print *ndr, const char *name, enum spoolss_NotifyTable r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 2faeea2e40..756a992e17 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -1072,6 +1072,9 @@ struct spoolss_NotifyOptionType { enum spoolss_Field *fields;/* [unique,size_is(count)] */ }; +/* bitmap spoolssNotifyOptionFlags */ +#define PRINTER_NOTIFY_OPTIONS_REFRESH ( 0x00000001 ) + struct spoolss_NotifyOption { uint32_t version;/* [value(2)] */ uint32_t flags; diff --git a/librpc/gen_ndr/srv_eventlog.c b/librpc/gen_ndr/srv_eventlog.c index 795afc9a5a..2cab792adf 100644 --- a/librpc/gen_ndr/srv_eventlog.c +++ b/librpc/gen_ndr/srv_eventlog.c @@ -1673,18 +1673,18 @@ static bool api_eventlog_WriteClusterEvents(pipes_struct *p) return true; } -static bool api_eventlog_GetLogIntormation(pipes_struct *p) +static bool api_eventlog_GetLogInformation(pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; DATA_BLOB blob; - struct eventlog_GetLogIntormation *r; + struct eventlog_GetLogInformation *r; - call = &ndr_table_eventlog.calls[NDR_EVENTLOG_GETLOGINTORMATION]; + call = &ndr_table_eventlog.calls[NDR_EVENTLOG_GETLOGINFORMATION]; - r = talloc(talloc_tos(), struct eventlog_GetLogIntormation); + r = talloc(talloc_tos(), struct eventlog_GetLogInformation); if (r == NULL) { return false; } @@ -1708,7 +1708,7 @@ static bool api_eventlog_GetLogIntormation(pipes_struct *p) } if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(eventlog_GetLogIntormation, r); + NDR_PRINT_IN_DEBUG(eventlog_GetLogInformation, r); } ZERO_STRUCT(r->out); @@ -1724,7 +1724,7 @@ static bool api_eventlog_GetLogIntormation(pipes_struct *p) return false; } - r->out.result = _eventlog_GetLogIntormation(p, r); + r->out.result = _eventlog_GetLogInformation(p, r); if (p->rng_fault_state) { talloc_free(r); @@ -1733,7 +1733,7 @@ static bool api_eventlog_GetLogIntormation(pipes_struct *p) } if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(eventlog_GetLogIntormation, r); + NDR_PRINT_OUT_DEBUG(eventlog_GetLogInformation, r); } push = ndr_push_init_ctx(r, NULL); @@ -1934,7 +1934,7 @@ static struct api_struct api_eventlog_cmds[] = {"EVENTLOG_REGISTERCLUSTERSVC", NDR_EVENTLOG_REGISTERCLUSTERSVC, api_eventlog_RegisterClusterSvc}, {"EVENTLOG_DEREGISTERCLUSTERSVC", NDR_EVENTLOG_DEREGISTERCLUSTERSVC, api_eventlog_DeregisterClusterSvc}, {"EVENTLOG_WRITECLUSTEREVENTS", NDR_EVENTLOG_WRITECLUSTEREVENTS, api_eventlog_WriteClusterEvents}, - {"EVENTLOG_GETLOGINTORMATION", NDR_EVENTLOG_GETLOGINTORMATION, api_eventlog_GetLogIntormation}, + {"EVENTLOG_GETLOGINFORMATION", NDR_EVENTLOG_GETLOGINFORMATION, api_eventlog_GetLogInformation}, {"EVENTLOG_FLUSHEVENTLOG", NDR_EVENTLOG_FLUSHEVENTLOG, api_eventlog_FlushEventLog}, {"EVENTLOG_REPORTEVENTANDSOURCEW", NDR_EVENTLOG_REPORTEVENTANDSOURCEW, api_eventlog_ReportEventAndSourceW}, }; @@ -2138,8 +2138,8 @@ NTSTATUS rpc_eventlog_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - case NDR_EVENTLOG_GETLOGINTORMATION: { - struct eventlog_GetLogIntormation *r = (struct eventlog_GetLogIntormation *)_r; + case NDR_EVENTLOG_GETLOGINFORMATION: { + struct eventlog_GetLogInformation *r = (struct eventlog_GetLogInformation *)_r; ZERO_STRUCT(r->out); r->out.buffer = talloc_zero_array(mem_ctx, uint8_t, r->in.buf_size); if (r->out.buffer == NULL) { @@ -2151,7 +2151,7 @@ NTSTATUS rpc_eventlog_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - r->out.result = _eventlog_GetLogIntormation(cli->pipes_struct, r); + r->out.result = _eventlog_GetLogInformation(cli->pipes_struct, r); return NT_STATUS_OK; } diff --git a/librpc/gen_ndr/srv_eventlog.h b/librpc/gen_ndr/srv_eventlog.h index 11d6886a24..7da7cddbd2 100644 --- a/librpc/gen_ndr/srv_eventlog.h +++ b/librpc/gen_ndr/srv_eventlog.h @@ -23,7 +23,7 @@ NTSTATUS _eventlog_ReportEventA(pipes_struct *p, struct eventlog_ReportEventA *r NTSTATUS _eventlog_RegisterClusterSvc(pipes_struct *p, struct eventlog_RegisterClusterSvc *r); NTSTATUS _eventlog_DeregisterClusterSvc(pipes_struct *p, struct eventlog_DeregisterClusterSvc *r); NTSTATUS _eventlog_WriteClusterEvents(pipes_struct *p, struct eventlog_WriteClusterEvents *r); -NTSTATUS _eventlog_GetLogIntormation(pipes_struct *p, struct eventlog_GetLogIntormation *r); +NTSTATUS _eventlog_GetLogInformation(pipes_struct *p, struct eventlog_GetLogInformation *r); NTSTATUS _eventlog_FlushEventLog(pipes_struct *p, struct eventlog_FlushEventLog *r); NTSTATUS _eventlog_ReportEventAndSourceW(pipes_struct *p, struct eventlog_ReportEventAndSourceW *r); void eventlog_get_pipe_fns(struct api_struct **fns, int *n_fns); @@ -50,7 +50,7 @@ NTSTATUS _eventlog_ReportEventA(pipes_struct *p, struct eventlog_ReportEventA *r NTSTATUS _eventlog_RegisterClusterSvc(pipes_struct *p, struct eventlog_RegisterClusterSvc *r); NTSTATUS _eventlog_DeregisterClusterSvc(pipes_struct *p, struct eventlog_DeregisterClusterSvc *r); NTSTATUS _eventlog_WriteClusterEvents(pipes_struct *p, struct eventlog_WriteClusterEvents *r); -NTSTATUS _eventlog_GetLogIntormation(pipes_struct *p, struct eventlog_GetLogIntormation *r); +NTSTATUS _eventlog_GetLogInformation(pipes_struct *p, struct eventlog_GetLogInformation *r); NTSTATUS _eventlog_FlushEventLog(pipes_struct *p, struct eventlog_FlushEventLog *r); NTSTATUS _eventlog_ReportEventAndSourceW(pipes_struct *p, struct eventlog_ReportEventAndSourceW *r); NTSTATUS rpc_eventlog_init(void); -- cgit From 24373c16a5b3e96ea3adc18e7aac837be59fb2c2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Feb 2009 14:22:39 +0100 Subject: s4-smbtorture: fix eventlog getinformation test. Guenther --- source4/torture/rpc/eventlog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c index 2fd9d923f1..10c4886259 100644 --- a/source4/torture/rpc/eventlog.c +++ b/source4/torture/rpc/eventlog.c @@ -306,7 +306,7 @@ static bool test_GetLogInformation(struct torture_context *tctx, struct dcerpc_pipe *p) { NTSTATUS status; - struct eventlog_GetLogIntormation r; + struct eventlog_GetLogInformation r; struct eventlog_CloseEventLog cr; struct policy_handle handle; uint32_t bytes_needed = 0; @@ -320,14 +320,14 @@ static bool test_GetLogInformation(struct torture_context *tctx, r.out.buffer = NULL; r.out.bytes_needed = &bytes_needed; - status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + status = dcerpc_eventlog_GetLogInformation(p, tctx, &r); torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_LEVEL, "GetLogInformation failed"); r.in.level = 0; - status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + status = dcerpc_eventlog_GetLogInformation(p, tctx, &r); torture_assert_ntstatus_equal(tctx, status, NT_STATUS_BUFFER_TOO_SMALL, "GetLogInformation failed"); @@ -335,7 +335,7 @@ static bool test_GetLogInformation(struct torture_context *tctx, r.in.buf_size = bytes_needed; r.out.buffer = talloc_array(tctx, uint8_t, bytes_needed); - status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + status = dcerpc_eventlog_GetLogInformation(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetLogInformation failed"); -- cgit From 762b92e285b7d98936393fc61a5ab18c66e9d534 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Feb 2009 14:24:59 +0100 Subject: s3-eventlog: fix rpcclient and server stub for eventlog_GetLogInformation. Guenther --- source3/rpc_server/srv_eventlog_nt.c | 2 +- source3/rpcclient/cmd_eventlog.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 697457888e..2f163a379f 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -706,7 +706,7 @@ NTSTATUS _eventlog_WriteClusterEvents(pipes_struct *p, struct eventlog_WriteClus return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _eventlog_GetLogIntormation(pipes_struct *p, struct eventlog_GetLogIntormation *r) +NTSTATUS _eventlog_GetLogInformation(pipes_struct *p, struct eventlog_GetLogInformation *r) { p->rng_fault_state = True; return NT_STATUS_NOT_IMPLEMENTED; diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c index e212452e5d..d839bf4263 100644 --- a/source3/rpcclient/cmd_eventlog.c +++ b/source3/rpcclient/cmd_eventlog.c @@ -454,7 +454,7 @@ static NTSTATUS cmd_eventlog_loginfo(struct rpc_pipe_client *cli, return status; } - status = rpccli_eventlog_GetLogIntormation(cli, mem_ctx, + status = rpccli_eventlog_GetLogInformation(cli, mem_ctx, &handle, 0, /* level */ buffer, @@ -472,7 +472,7 @@ static NTSTATUS cmd_eventlog_loginfo(struct rpc_pipe_client *cli, goto done; } - status = rpccli_eventlog_GetLogIntormation(cli, mem_ctx, + status = rpccli_eventlog_GetLogInformation(cli, mem_ctx, &handle, 0, /* level */ buffer, -- cgit From d3372c6a9e69360afd2f12168e9df09dec45ae08 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Feb 2009 14:55:31 +0100 Subject: s3-spoolss: fix _spoolss_GetPrinterDriverDirectory and spoolss_GetPrintProcessorDirectory. Both calls need to return NULL in the error case to avoid ndr encoding problems. (found by smbtorture spoolss test). Guenther --- source3/rpc_server/srv_spoolss_nt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 7439fe51a5..0fe66d9ed9 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -8309,7 +8309,7 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p, &r->out.info->info1, r->in.offered, r->out.needed); - if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + if (!W_ERROR_IS_OK(werror)) { TALLOC_FREE(r->out.info); } break; @@ -9969,7 +9969,7 @@ WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p, &r->out.info->info1, r->in.offered, r->out.needed); - if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) { + if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(r->out.info); } break; -- cgit From 35d6234998639fff444671ec04693043a1e28d07 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 21 Feb 2009 21:03:36 +0100 Subject: s3-spoolss: remove duplicate flag. Guenther --- source3/include/rpc_spoolss.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 99da007d32..670eca4ca4 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -209,8 +209,6 @@ #define JOB_NOTIFY_TOTAL_BYTES 0x16 #define JOB_NOTIFY_BYTES_PRINTED 0x17 -#define PRINTER_NOTIFY_OPTIONS_REFRESH 0x01 - /* * Set of macros for flagging what changed in the PRINTER_INFO_2 struct * when sending messages to other smbd's -- cgit From 2ad2b6f723964ed6e5d1d12c8403bd3d4147dc84 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 21 Feb 2009 21:07:37 +0100 Subject: s3-spoolss: fix client name in rpccli_spoolss_openprinter_ex. Guenther --- source3/rpc_client/cli_spoolss.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 489b9ca2ff..6ad3af1f4e 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -44,7 +44,8 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli, ZERO_STRUCT(devmode_ctr); level1.size = 28; - level1.client = cli->srv_name_slash; + level1.client = talloc_asprintf(mem_ctx, "\\\\%s", global_myname()); + W_ERROR_HAVE_NO_MEMORY(level1.client); level1.user = cli->auth->user_name; level1.build = 1381; level1.major = 2; -- cgit From 39b508e38e831f826be254391f7f341bc935f792 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sat, 21 Feb 2009 13:54:43 -0800 Subject: Fix shadowed declaration warning --- lib/util/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/util.h b/lib/util/util.h index 4d4df21600..d3e446f488 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -732,7 +732,7 @@ _PUBLIC_ void close_low_fds(bool stderr_too); /** Become a daemon, discarding the controlling terminal. **/ -_PUBLIC_ void become_daemon(bool fork, bool no_process_group); +_PUBLIC_ void become_daemon(bool do_fork, bool no_process_group); /** * Load a ini-style file. -- cgit From 1ff9696306894c136015f83456e4c6e039e31e26 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sat, 21 Feb 2009 13:57:10 -0800 Subject: Revert "s3 auth: Add parameter that forces every user through an NSS lookup" After the discussion on samba-technical, it was decided that the best answer for now was to revert this change. The right way to do this is to rewrite the token api to use opaque tokens with pluggable modules. This reverts commit 8e19a288052bca5efdb0277a40c1e0fdd099cc2b. --- source3/auth/auth_util.c | 26 ++++---------------------- source3/include/proto.h | 2 -- source3/param/loadparm.c | 11 ----------- 3 files changed, 4 insertions(+), 35 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 0dab05b97c..1f00e22a3c 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -710,8 +710,6 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info) NTSTATUS status; size_t i; struct dom_sid tmp_sid; - const char *name_to_use; - bool force_nss; /* * If winbind is not around, we can not make much use of the SIDs the @@ -719,22 +717,11 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info) * mapped to some local unix user. */ - DEBUG(10, ("creating token for %s (SAM: %s)\n", server_info->unix_name, - server_info->sam_account->username)); - - force_nss = lp_force_username_map() && !server_info->nss_token; if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) || - server_info->nss_token || force_nss) { - if (force_nss) - name_to_use = - pdb_get_username(server_info->sam_account); - else - name_to_use = server_info->unix_name; - + (server_info->nss_token)) { status = create_token_from_username(server_info, - name_to_use, + server_info->unix_name, server_info->guest, - force_nss, &server_info->utok.uid, &server_info->utok.gid, &server_info->unix_name, @@ -839,7 +826,6 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info) NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, bool is_guest, - bool force_nss, uid_t *uid, gid_t *gid, char **found_username, struct nt_user_token **token) @@ -855,9 +841,6 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, size_t num_gids; size_t i; - DEBUG(10, ("creating token for %s,%s guest,%s forcing NSS lookup\n", - username, is_guest ? "" : " not", force_nss ? "" : " not")); - tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(0, ("talloc_new failed\n")); @@ -882,7 +865,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, goto done; } - if (sid_check_is_in_our_domain(&user_sid) && !force_nss) { + if (sid_check_is_in_our_domain(&user_sid)) { bool ret; /* This is a passdb user, so ask passdb */ @@ -924,7 +907,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, *found_username = talloc_strdup(mem_ctx, pdb_get_username(sam_acct)); - } else if (force_nss || sid_check_is_in_unix_users(&user_sid)) { + } else if (sid_check_is_in_unix_users(&user_sid)) { /* This is a unix user not in passdb. We need to ask nss * directly, without consulting passdb */ @@ -1080,7 +1063,6 @@ bool user_in_group_sid(const char *username, const DOM_SID *group_sid) } status = create_token_from_username(mem_ctx, username, False, - lp_force_username_map(), &uid, &gid, &found_username, &token); diff --git a/source3/include/proto.h b/source3/include/proto.h index 587bb29042..9dc9719e48 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -110,7 +110,6 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, NTSTATUS create_local_token(auth_serversupplied_info *server_info); NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, bool is_guest, - bool force_nss, uid_t *uid, gid_t *gid, char **found_username, struct nt_user_token **token); @@ -3971,7 +3970,6 @@ const char *lp_afs_username_map(void); int lp_afs_token_lifetime(void); char *lp_log_nt_token_command(void); char *lp_username_map(void); -bool lp_force_username_map(void); const char *lp_logon_script(void); const char *lp_logon_path(void); const char *lp_logon_drive(void); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 3d29f3afd9..e50ab929ad 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -144,7 +144,6 @@ struct global { int iAfsTokenLifetime; char *szLogNtTokenCommand; char *szUsernameMap; - bool bForceUsernameMap; char *szLogonScript; char *szLogonPath; char *szLogonDrive; @@ -1282,15 +1281,6 @@ static struct parm_struct parm_table[] = { .enum_list = NULL, .flags = FLAG_ADVANCED, }, - { - .label = "force username map", - .type = P_BOOL, - .p_class = P_GLOBAL, - .ptr = &Globals.bForceUsernameMap, - .special = NULL, - .enum_list = NULL, - .flags = FLAG_ADVANCED, - }, { .label = "password level", .type = P_INTEGER, @@ -5246,7 +5236,6 @@ FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap) FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime) FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand) FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap) -FN_GLOBAL_BOOL(lp_force_username_map, &Globals.bForceUsernameMap) FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript) FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath) FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive) -- cgit From 0dcfa9ce1baa9f2074a002fdb5c8b88cc5db28db Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 20 Feb 2009 13:28:36 -0800 Subject: s3: If sendfile returns 0 bytes read, fall back to the normal read path This allows sendfile implementations that are atomic to avoid having to send zeros or kill the client connection on a short read (usually the file was truncated). --- source3/smbd/reply.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 457f9412a9..b30ef23c0e 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2788,6 +2788,18 @@ static void send_file_readbraw(connection_struct *conn, DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n", fsp->fsp_name, strerror(errno) )); exit_server_cleanly("send_file_readbraw sendfile failed"); + } else if (sendfile_read == 0) { + /* + * Some sendfile implementations return 0 to indicate + * that there was a short read, but nothing was + * actually written to the socket. In this case, + * fallback to the normal read path so the header gets + * the correct byte count. + */ + DEBUG(3, ("send_file_readbraw: sendfile sent zero " + "bytes falling back to the normal read: " + "%s\n", fsp->fsp_name)); + goto normal_readbraw; } /* Deal with possible short send. */ @@ -3284,6 +3296,18 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n", fsp->fsp_name, strerror(errno) )); exit_server_cleanly("send_file_readX sendfile failed"); + } else if (nread == 0) { + /* + * Some sendfile implementations return 0 to indicate + * that there was a short read, but nothing was + * actually written to the socket. In this case, + * fallback to the normal read path so the header gets + * the correct byte count. + */ + DEBUG(3, ("send_file_readX: sendfile sent zero bytes " + "falling back to the normal read: %s\n", + fsp->fsp_name)); + goto normal_read; } DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n", -- cgit From 8ec9903426ec4e559df8ac8306a8ebcdf0706176 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 20 Feb 2009 13:27:39 -0800 Subject: s3 OneFS: Add an atomic sendfile implementation --- source3/modules/onefs.h | 10 ++ source3/modules/onefs_system.c | 257 +++++++++++++++++++++++++++++++++++++++++ source3/modules/vfs_onefs.c | 15 +++ 3 files changed, 282 insertions(+) diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index ea452a454d..a70664bbf3 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -47,6 +47,8 @@ enum onefs_acl_wire_format #define PARM_ATIME_STATIC_DEFAULT NULL #define PARM_ATIME_SLOP "atime now slop" #define PARM_ATIME_SLOP_DEFAULT 0 +#define PARM_ATOMIC_SENDFILE "atomic sendfile" +#define PARM_ATOMIC_SENDFILE_DEFAULT true #define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control" #define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true #define PARM_CTIME_NOW "ctime now files" @@ -63,6 +65,10 @@ enum onefs_acl_wire_format #define PARM_MTIME_SLOP_DEFAULT 0 #define PARM_USE_READDIRPLUS "use readdirplus" #define PARM_USE_READDIRPLUS_DEFAULT true +#define PARM_SENDFILE_LARGE_READS "sendfile large reads" +#define PARM_SENDFILE_LARGE_READS_DEFAULT false +#define PARM_SENDFILE_SAFE "sendfile safe" +#define PARM_SENDFILE_SAFE_DEFAULT true #define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE "simple file sharing compatibility mode" #define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false #define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone" @@ -254,6 +260,10 @@ int onefs_sys_create_file(connection_struct *conn, uint32_t ntfs_flags, int *granted_oplock); +ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, + const DATA_BLOB *header, SMB_OFF_T offset, + size_t count); + ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, size_t count); diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 3a86b4b815..10802895cd 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -177,6 +177,263 @@ int onefs_sys_create_file(connection_struct *conn, return ret_fd; } +/** + * FreeBSD based sendfile implementation that allows for atomic semantics. + */ +static ssize_t onefs_sys_do_sendfile(int tofd, int fromfd, + const DATA_BLOB *header, SMB_OFF_T offset, size_t count, bool atomic) +{ + size_t total=0; + struct sf_hdtr hdr; + struct iovec hdtrl; + size_t hdr_len = 0; + int flags = 0; + + if (atomic) { + flags = SF_ATOMIC; + } + + hdr.headers = &hdtrl; + hdr.hdr_cnt = 1; + hdr.trailers = NULL; + hdr.trl_cnt = 0; + + /* Set up the header iovec. */ + if (header) { + hdtrl.iov_base = header->data; + hdtrl.iov_len = hdr_len = header->length; + } else { + hdtrl.iov_base = NULL; + hdtrl.iov_len = 0; + } + + total = count; + while (total + hdtrl.iov_len) { + SMB_OFF_T nwritten; + int ret; + + /* + * FreeBSD sendfile returns 0 on success, -1 on error. + * Remember, the tofd and fromfd are reversed..... :-). + * nwritten includes the header data sent. + */ + + do { + ret = sendfile(fromfd, tofd, offset, total, &hdr, + &nwritten, flags); + } while (ret == -1 && errno == EINTR); + + /* On error we're done. */ + if (ret == -1) { + return -1; + } + + /* + * If this was an ATOMIC sendfile, nwritten doesn't + * necessarily indicate an error. It could mean count > than + * what sendfile can handle atomically (usually 64K) or that + * there was a short read due to the file being truncated. + */ + if (nwritten == 0) { + return atomic ? 0 : -1; + } + + /* + * An atomic sendfile should never send partial data! + */ + if (atomic && nwritten != total + hdtrl.iov_len) { + DEBUG(0,("Atomic sendfile() sent partial data: " + "%llu of %d\n", nwritten, + total + hdtrl.iov_len)); + return -1; + } + + /* + * If this was a short (signal interrupted) write we may need + * to subtract it from the header data, or null out the header + * data altogether if we wrote more than hdtrl.iov_len bytes. + * We change nwritten to be the number of file bytes written. + */ + + if (hdtrl.iov_base && hdtrl.iov_len) { + if (nwritten >= hdtrl.iov_len) { + nwritten -= hdtrl.iov_len; + hdtrl.iov_base = NULL; + hdtrl.iov_len = 0; + } else { + hdtrl.iov_base = + (caddr_t)hdtrl.iov_base + nwritten; + hdtrl.iov_len -= nwritten; + nwritten = 0; + } + } + total -= nwritten; + offset += nwritten; + } + return count + hdr_len; +} + +/** + * Handles the subtleties of using sendfile with CIFS. + */ +ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, + const DATA_BLOB *header, SMB_OFF_T offset, + size_t count) +{ + bool atomic = false; + ssize_t ret = 0; + + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_ATOMIC_SENDFILE, + PARM_ATOMIC_SENDFILE_DEFAULT)) { + atomic = true; + } + + /* Try the sendfile */ + ret = onefs_sys_do_sendfile(tofd, fromfd, header, offset, count, + atomic); + + /* If the sendfile wasn't atomic, we're done. */ + if (!atomic) { + DEBUG(10, ("non-atomic sendfile read %ul bytes", ret)); + return ret; + } + + /* + * Atomic sendfile takes care to not write anything to the socket + * until all of the requested bytes have been read from the file. + * There are two atomic cases that need to be handled. + * + * 1. The file was truncated causing less data to be read than was + * requested. In this case, we return back to the caller to + * indicate 0 bytes were written to the socket. This should + * prompt the caller to fallback to the standard read path: read + * the data, create a header that indicates how many bytes were + * actually read, and send the header/data back to the client. + * + * This saves us from standard sendfile behavior of sending a + * header promising more data then will actually be sent. The + * only two options are to close the socket and kill the client + * connection, or write a bunch of 0s. Closing the client + * connection is bad because there could actually be multiple + * sessions multiplexed from the same client that are all dropped + * because of a truncate. Writing the remaining data as 0s also + * isn't good, because the client will have an incorrect version + * of the file. If the file is written back to the server, the 0s + * will be written back. Fortunately, atomic sendfile allows us + * to avoid making this choice in most cases. + * + * 2. One downside of atomic sendfile, is that there is a limit on + * the number of bytes that can be sent atomically. The kernel + * has a limited amount of mbuf space that it can read file data + * into without exhausting the system's mbufs, so a buffer of + * length xfsize is used. The xfsize at the time of writing this + * is 64K. xfsize bytes are read from the file, and subsequently + * written to the socket. This makes it impossible to do the + * sendfile atomically for a byte count > xfsize. + * + * To cope with large requests, atomic sendfile returns -1 with + * errno set to E2BIG. Since windows maxes out at 64K writes, + * this is currently only a concern with non-windows clients. + * Posix extensions allow the full 24bit bytecount field to be + * used in ReadAndX, and clients such as smbclient and the linux + * cifs client can request up to 16MB reads! There are a few + * options for handling large sendfile requests. + * + * a. Fall back to the standard read path. This is unacceptable + * because it would require prohibitively large mallocs. + * + * b. Fall back to using samba's fake_send_file which emulates + * the kernel sendfile in userspace. This still has the same + * problem of sending the header before all of the data has + * been read, so it doesn't buy us anything, and has worse + * performance than the kernel's zero-copy sendfile. + * + * c. Use non-atomic sendfile syscall to attempt a zero copy + * read, and hope that there isn't a short read due to + * truncation. In the case of a short read, there are two + * options: + * + * 1. Kill the client connection + * + * 2. Write zeros to the socket for the remaining bytes + * promised in the header. + * + * It is safer from a data corruption perspective to kill the + * client connection, so this is our default behavior, but if + * this causes problems this can be configured to write zeros + * via smb.conf. + */ + + /* Handle case 1: short read -> truncated file. */ + if (ret == 0) { + return ret; + } + + /* Handle case 2: large read. */ + if (ret == -1 && errno == E2BIG) { + + if (!lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_SENDFILE_LARGE_READS, + PARM_SENDFILE_LARGE_READS_DEFAULT)) { + DEBUG(3, ("Not attempting non-atomic large sendfile: " + "%lu bytes\n", count)); + return 0; + } + + if (count < 0x10000) { + DEBUG(0, ("Count < 2^16 and E2BIG was returned! %lu", + count)); + } + + DEBUG(10, ("attempting non-atomic large sendfile: %lu bytes\n", + count)); + + /* Try a non-atomic sendfile. */ + ret = onefs_sys_do_sendfile(tofd, fromfd, header, offset, + count, false); + /* Real error: kill the client connection. */ + if (ret == -1) { + DEBUG(1, ("error on non-atomic large sendfile " + "(%lu bytes): %s\n", count, + strerror(errno))); + return ret; + } + + /* Short read: kill the client connection. */ + if (ret != count + header->length) { + DEBUG(1, ("short read on non-atomic large sendfile " + "(%lu of %lu bytes): %s\n", ret, count, + strerror(errno))); + + /* + * Returning ret here would cause us to drop into the + * codepath that calls sendfile_short_send, which + * sends the client a bunch of zeros instead. + * Returning -1 kills the connection. + */ + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_SENDFILE_SAFE, + PARM_SENDFILE_SAFE_DEFAULT)) { + return -1; + } + + return ret; + } + + DEBUG(10, ("non-atomic large sendfile successful\n")); + } + + /* There was error in the atomic sendfile. */ + if (ret == -1) { + DEBUG(1, ("error on %s sendfile (%lu bytes): %s\n", + atomic ? "atomic" : "non-atomic", + count, strerror(errno))); + } + + return ret; +} + /** * Only talloc the spill buffer once (reallocing when necessary). */ diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index f0c6a9d8bb..60c2c977a4 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -156,6 +156,19 @@ static int onefs_open(vfs_handle_struct *handle, const char *fname, return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); } +static ssize_t onefs_sendfile(vfs_handle_struct *handle, int tofd, + files_struct *fromfsp, const DATA_BLOB *header, + SMB_OFF_T offset, size_t count) +{ + ssize_t result; + + START_PROFILE_BYTES(syscall_sendfile, count); + result = onefs_sys_sendfile(handle->conn, tofd, fromfsp->fh->fd, + header, offset, count); + END_PROFILE(syscall_sendfile); + return result; +} + static ssize_t onefs_recvfile(vfs_handle_struct *handle, int fromfd, files_struct *tofsp, SMB_OFF_T offset, size_t count) @@ -340,6 +353,8 @@ static vfs_op_tuple onefs_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_sendfile), SMB_VFS_OP_SENDFILE, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_recvfile), SMB_VFS_OP_RECVFILE, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_rename), SMB_VFS_OP_RENAME, -- cgit From 4e5997736c6e173ddfd735239ac5c77d2353a5f6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 22 Feb 2009 01:06:28 -0500 Subject: For some unknown reason ldbrename was not being built in samba3. --- docs-xml/manpages-3/ldbrename.1.xml | 107 ++++++++++++++++++++++++++++++++++++ source3/Makefile.in | 9 ++- 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 docs-xml/manpages-3/ldbrename.1.xml diff --git a/docs-xml/manpages-3/ldbrename.1.xml b/docs-xml/manpages-3/ldbrename.1.xml new file mode 100644 index 0000000000..391ec84ccc --- /dev/null +++ b/docs-xml/manpages-3/ldbrename.1.xml @@ -0,0 +1,107 @@ + + + + + + ldbrename + 1 + + + + + ldbrename + Edit LDB databases using your favorite editor + + + + + ldbrename + -h + -o options + olddn + newdb + + + + + DESCRIPTION + + ldbrename is a utility that allows you to rename trees in + an LDB database based by DN. This utility takes + two arguments: the original + DN name of the top element and the DN to change it to. + + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(7) for details. + + + + + -o options + Extra ldb options, such as + modules. + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overrided by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + ldb(7), ldbmodify, ldbdel, ldif(5) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/source3/Makefile.in b/source3/Makefile.in index 6087fa0359..d4a849cbc7 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -197,7 +197,7 @@ BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \ bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ bin/sharesec@EXEEXT@ \ bin/smbcquotas@EXEEXT@ bin/eventlogadm@EXEEXT@ BIN_PROGS4 = bin/ldbedit@EXEEXT@ bin/ldbsearch@EXEEXT@ bin/ldbadd@EXEEXT@ \ - bin/ldbdel@EXEEXT@ bin/ldbmodify@EXEEXT@ + bin/ldbdel@EXEEXT@ bin/ldbmodify@EXEEXT@ bin/ldbrename@EXEEXT@ TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \ bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \ @@ -1128,6 +1128,7 @@ LDBSEARCH_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbsearch.o LDBADD_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbadd.o LDBDEL_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbdel.o LDBMODIFY_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbmodify.o +LDBRENAME_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbrename.o WINBIND_KRB5_LOCATOR_OBJ1 = ../nsswitch/winbind_krb5_locator.o WINBIND_KRB5_LOCATOR_OBJ = $(WINBIND_KRB5_LOCATOR_OBJ1) $(LIBREPLACE_OBJ) @@ -1619,6 +1620,12 @@ bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIB $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) +bin/ldbrename: $(BINARY_PREREQS) $(LDBRENAME_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(LDBRENAME_OBJ) $(DYNEXP) $(LDFLAGS) \ + $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + ##################################################################### # -- cgit From ac0d452ac64cae90645ad49b1bb04f2e8bf89c9b Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Sun, 22 Feb 2009 21:55:25 -0800 Subject: s3: Wrap usage of rlimit in configure checks --- source3/param/loadparm.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index e50ab929ad..89c706d874 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4656,32 +4656,31 @@ static void init_printer_values(struct service *pService) static int max_open_files(void) { int sysctl_max = MAX_OPEN_FILES; - struct rlimit rl; - bool sysctl_worked = false, rlimit_worked = false; + int rlimit_max = MAX_OPEN_FILES; #ifdef HAVE_SYSCTLBYNAME - size_t size = sizeof(sysctl_max); - if (sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,0)==0) - sysctl_worked = true; + { + size_t size = sizeof(sysctl_max); + sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL, + 0); + } #endif - if (getrlimit(RLIMIT_NOFILE, &rl) == 0) - rlimit_worked = true; +#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) + { + struct rlimit rl = {}; - if (sysctl_worked) { - if ((!rlimit_worked) || - (rl.rlim_cur == RLIM_INFINITY) || - (rl.rlim_cur > sysctl_max)) - return sysctl_max; - else - return rl.rlim_cur; - } else { - if ((!rlimit_worked) || - (rl.rlim_cur == RLIM_INFINITY)) - return MAX_OPEN_FILES; - else - return rl.rlim_cur; + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) + rlimit_max = rl.rlim_cur; + +#if defined(RLIM_INFINITY) + if(rl.rlim_cur == RLIM_INFINITY) + rlimit_max = MAX_OPEN_FILES; } +#endif +#endif + + return MIN(sysctl_max, rlimit_max); } /** -- cgit From 09a7f93f6be66a8f2a124e49b4effe2b5863f01d Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Mon, 23 Feb 2009 09:24:50 +0100 Subject: s3/docs: Fix typo in man mount.cifs. Thanks to Tobias Stoeckmann for reporting! Karolin --- docs-xml/manpages-3/mount.cifs.8.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/manpages-3/mount.cifs.8.xml b/docs-xml/manpages-3/mount.cifs.8.xml index c386592f1d..ca8ae5f4bf 100644 --- a/docs-xml/manpages-3/mount.cifs.8.xml +++ b/docs-xml/manpages-3/mount.cifs.8.xml @@ -140,7 +140,7 @@ credentials file properly. same domain (e.g. running winbind or nss_ldap) and the server supports the Unix Extensions then the uid and gid can be retrieved from the server (and uid - and gid would not have to be specifed on the mount. + and gid would not have to be specified on the mount. For servers which do not support the CIFS Unix extensions, the default uid (and gid) returned on lookup of existing files will be the uid (gid) of the person -- cgit From cd6ae0de52164dd6f50b3614f2511acb3eb15993 Mon Sep 17 00:00:00 2001 From: Bjƶrn Jacke Date: Sun, 22 Feb 2009 00:43:38 +0100 Subject: all BSDs use this evironment variable Signed-off-by: Stefan Metzmacher --- lib/replace/libreplace_ld.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/replace/libreplace_ld.m4 b/lib/replace/libreplace_ld.m4 index 81bde46219..9529c5e0a5 100644 --- a/lib/replace/libreplace_ld.m4 +++ b/lib/replace/libreplace_ld.m4 @@ -292,7 +292,7 @@ AC_DEFUN([AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR], *linux*) LIB_PATH_VAR=LD_LIBRARY_PATH ;; - *netbsd*) + *bsd*) LIB_PATH_VAR=LD_LIBRARY_PATH ;; *solaris*) -- cgit From 672eb22bc1ee6ee7d3372655f0847f676727643a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 21 Feb 2009 23:11:49 +0100 Subject: spoolss: fix some PRINTER_CHANGE_ defines (and add a new windows 7 flag). Guenther --- librpc/idl/spoolss.idl | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index b441f17cf1..ca33cd1192 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1530,21 +1530,16 @@ import "misc.idl", "security.idl", "winreg.idl"; PRINTER_CHANGE_DELETE_PORT = 0x00400000, PRINTER_CHANGE_ADD_PRINT_PROCESSOR = 0x01000000, PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = 0x04000000, + PRINTER_CHANGE_SERVER = 0x08000000, PRINTER_CHANGE_ADD_PRINTER_DRIVER = 0x10000000, PRINTER_CHANGE_SET_PRINTER_DRIVER = 0x20000000, PRINTER_CHANGE_DELETE_PRINTER_DRIVER = 0x40000000, PRINTER_CHANGE_TIMEOUT = 0x80000000 } spoolss_PrinterChangeFlags; - const int PRINTER_CHANGE_PRINTER = (PRINTER_CHANGE_ADD_PRINTER | - PRINTER_CHANGE_SET_PRINTER | - PRINTER_CHANGE_DELETE_PRINTER | - PRINTER_CHANGE_FAILED_CONNECTION_PRINTER); /* 0x000000FF */ + const int PRINTER_CHANGE_PRINTER = 0x000000FF; - const int PRINTER_CHANGE_JOB = (PRINTER_CHANGE_ADD_JOB | - PRINTER_CHANGE_SET_JOB | - PRINTER_CHANGE_DELETE_JOB | - PRINTER_CHANGE_WRITE_JOB); /* 0x0000FF00 */ + const int PRINTER_CHANGE_JOB = 0x0000FF00; const int PRINTER_CHANGE_FORM = (PRINTER_CHANGE_ADD_FORM | PRINTER_CHANGE_SET_FORM | @@ -1554,14 +1549,14 @@ import "misc.idl", "security.idl", "winreg.idl"; PRINTER_CHANGE_CONFIGURE_PORT | PRINTER_CHANGE_DELETE_PORT); /* 0x00700000 */ - const int PRINTER_CHANGE_PRINT_PROCESSOR = (PRINTER_CHANGE_ADD_PRINT_PROCESSOR | - PRINTER_CHANGE_DELETE_PRINT_PROCESSOR); /* 0x07000000 */ + const int PRINTER_CHANGE_PRINT_PROCESSOR = 0x07000000; const int PRINTER_CHANGE_PRINTER_DRIVER = (PRINTER_CHANGE_ADD_PRINTER_DRIVER | PRINTER_CHANGE_SET_PRINTER_DRIVER | PRINTER_CHANGE_DELETE_PRINTER_DRIVER); /* 0x70000000 */ - const int PRINTER_CHANGE_ALL = (PRINTER_CHANGE_JOB | + const int PRINTER_CHANGE_ALL = (PRINTER_CHANGE_PRINTER | + PRINTER_CHANGE_JOB | PRINTER_CHANGE_FORM | PRINTER_CHANGE_PORT | PRINTER_CHANGE_PRINT_PROCESSOR | -- cgit From db400032abc48baafaef87d72e6498505642bf34 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 11:50:27 +0100 Subject: spoolss: spoolss_NotifyData contains a devmode container, not devmode pointer. Guenther --- librpc/idl/spoolss.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index ca33cd1192..17d480261a 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1678,7 +1678,7 @@ import "misc.idl", "security.idl", "winreg.idl"; typedef [switch_type(uint32)] union { [case(1)] uint32 integer[2]; [case(2)] spoolss_NotifyString string; - [case(3)] spoolss_DeviceMode *devmode; + [case(3)] spoolss_DevmodeContainer devmode; [case(4)] spoolss_TimeCtr time; [case(5)] sec_desc_buf sd; } spoolss_NotifyData; -- cgit From e2ab5a155cd8b20d1dce91fa2f31d840c673a3b6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 12:47:53 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 30 ++++++------------------------ librpc/gen_ndr/spoolss.h | 11 ++++++----- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index b0d5366636..242041fb8d 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -13053,6 +13053,7 @@ _PUBLIC_ void ndr_print_spoolss_PrinterChangeFlags(struct ndr_print *ndr, const ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_CHANGE_DELETE_PORT", PRINTER_CHANGE_DELETE_PORT, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_CHANGE_ADD_PRINT_PROCESSOR", PRINTER_CHANGE_ADD_PRINT_PROCESSOR, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_CHANGE_DELETE_PRINT_PROCESSOR", PRINTER_CHANGE_DELETE_PRINT_PROCESSOR, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_CHANGE_SERVER", PRINTER_CHANGE_SERVER, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_CHANGE_ADD_PRINTER_DRIVER", PRINTER_CHANGE_ADD_PRINTER_DRIVER, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_CHANGE_SET_PRINTER_DRIVER", PRINTER_CHANGE_SET_PRINTER_DRIVER, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_CHANGE_DELETE_PRINTER_DRIVER", PRINTER_CHANGE_DELETE_PRINTER_DRIVER, r); @@ -13445,7 +13446,7 @@ static enum ndr_err_code ndr_push_spoolss_NotifyData(struct ndr_push *ndr, int n break; } case 3: { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->devmode)); + NDR_CHECK(ndr_push_spoolss_DevmodeContainer(ndr, NDR_SCALARS, &r->devmode)); break; } case 4: { @@ -13471,9 +13472,7 @@ static enum ndr_err_code ndr_push_spoolss_NotifyData(struct ndr_push *ndr, int n break; case 3: - if (r->devmode) { - NDR_CHECK(ndr_push_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); - } + NDR_CHECK(ndr_push_spoolss_DevmodeContainer(ndr, NDR_BUFFERS, &r->devmode)); break; case 4: @@ -13495,7 +13494,6 @@ static enum ndr_err_code ndr_pull_spoolss_NotifyData(struct ndr_pull *ndr, int n { int level; uint32_t _level; - TALLOC_CTX *_mem_save_devmode_0; level = ndr_pull_get_switch_value(ndr, r); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level)); @@ -13515,13 +13513,7 @@ static enum ndr_err_code ndr_pull_spoolss_NotifyData(struct ndr_pull *ndr, int n break; } case 3: { - uint32_t _ptr_devmode; - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_devmode)); - if (_ptr_devmode) { - NDR_PULL_ALLOC(ndr, r->devmode); - } else { - r->devmode = NULL; - } + NDR_CHECK(ndr_pull_spoolss_DevmodeContainer(ndr, NDR_SCALARS, &r->devmode)); break; } case 4: { @@ -13546,12 +13538,7 @@ static enum ndr_err_code ndr_pull_spoolss_NotifyData(struct ndr_pull *ndr, int n break; case 3: - if (r->devmode) { - _mem_save_devmode_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->devmode, 0); - NDR_CHECK(ndr_pull_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_0, 0); - } + NDR_CHECK(ndr_pull_spoolss_DevmodeContainer(ndr, NDR_BUFFERS, &r->devmode)); break; case 4: @@ -13594,12 +13581,7 @@ _PUBLIC_ void ndr_print_spoolss_NotifyData(struct ndr_print *ndr, const char *na break; case 3: - ndr_print_ptr(ndr, "devmode", r->devmode); - ndr->depth++; - if (r->devmode) { - ndr_print_spoolss_DeviceMode(ndr, "devmode", r->devmode); - } - ndr->depth--; + ndr_print_spoolss_DevmodeContainer(ndr, "devmode", &r->devmode); break; case 4: diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 756a992e17..150bf04d6f 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -10,13 +10,13 @@ #define PRINTER_ENUM_ICONMASK ( (PRINTER_ENUM_ICON1|PRINTER_ENUM_ICON2|PRINTER_ENUM_ICON3|PRINTER_ENUM_ICON4|PRINTER_ENUM_ICON5|PRINTER_ENUM_ICON6|PRINTER_ENUM_ICON7|PRINTER_ENUM_ICON8) ) #define SPOOLSS_ARCHITECTURE_NT_X86 ( "Windows NT x86" ) -#define PRINTER_CHANGE_PRINTER ( (PRINTER_CHANGE_ADD_PRINTER|PRINTER_CHANGE_SET_PRINTER|PRINTER_CHANGE_DELETE_PRINTER|PRINTER_CHANGE_FAILED_CONNECTION_PRINTER) ) -#define PRINTER_CHANGE_JOB ( (PRINTER_CHANGE_ADD_JOB|PRINTER_CHANGE_SET_JOB|PRINTER_CHANGE_DELETE_JOB|PRINTER_CHANGE_WRITE_JOB) ) +#define PRINTER_CHANGE_PRINTER ( 0x000000FF ) +#define PRINTER_CHANGE_JOB ( 0x0000FF00 ) #define PRINTER_CHANGE_FORM ( (PRINTER_CHANGE_ADD_FORM|PRINTER_CHANGE_SET_FORM|PRINTER_CHANGE_DELETE_FORM) ) #define PRINTER_CHANGE_PORT ( (PRINTER_CHANGE_ADD_PORT|PRINTER_CHANGE_CONFIGURE_PORT|PRINTER_CHANGE_DELETE_PORT) ) -#define PRINTER_CHANGE_PRINT_PROCESSOR ( (PRINTER_CHANGE_ADD_PRINT_PROCESSOR|PRINTER_CHANGE_DELETE_PRINT_PROCESSOR) ) +#define PRINTER_CHANGE_PRINT_PROCESSOR ( 0x07000000 ) #define PRINTER_CHANGE_PRINTER_DRIVER ( (PRINTER_CHANGE_ADD_PRINTER_DRIVER|PRINTER_CHANGE_SET_PRINTER_DRIVER|PRINTER_CHANGE_DELETE_PRINTER_DRIVER) ) -#define PRINTER_CHANGE_ALL ( (PRINTER_CHANGE_JOB|PRINTER_CHANGE_FORM|PRINTER_CHANGE_PORT|PRINTER_CHANGE_PRINT_PROCESSOR|PRINTER_CHANGE_PRINTER_DRIVER) ) +#define PRINTER_CHANGE_ALL ( (PRINTER_CHANGE_PRINTER|PRINTER_CHANGE_JOB|PRINTER_CHANGE_FORM|PRINTER_CHANGE_PORT|PRINTER_CHANGE_PRINT_PROCESSOR|PRINTER_CHANGE_PRINTER_DRIVER) ) #define SERVER_ALL_ACCESS ( SEC_STD_REQUIRED|SERVER_ACCESS_ADMINISTER|SERVER_ACCESS_ENUMERATE ) #define SERVER_READ ( SEC_STD_READ_CONTROL|SERVER_ACCESS_ENUMERATE ) #define SERVER_WRITE ( STANDARD_RIGHTS_WRITE_ACCESS|SERVER_ACCESS_ADMINISTER|SERVER_ACCESS_ENUMERATE ) @@ -984,6 +984,7 @@ union spoolss_MonitorInfo { #define PRINTER_CHANGE_DELETE_PORT ( 0x00400000 ) #define PRINTER_CHANGE_ADD_PRINT_PROCESSOR ( 0x01000000 ) #define PRINTER_CHANGE_DELETE_PRINT_PROCESSOR ( 0x04000000 ) +#define PRINTER_CHANGE_SERVER ( 0x08000000 ) #define PRINTER_CHANGE_ADD_PRINTER_DRIVER ( 0x10000000 ) #define PRINTER_CHANGE_SET_PRINTER_DRIVER ( 0x20000000 ) #define PRINTER_CHANGE_DELETE_PRINTER_DRIVER ( 0x40000000 ) @@ -1109,7 +1110,7 @@ enum spoolss_NotifyTable union spoolss_NotifyData { uint32_t integer[2];/* [case] */ struct spoolss_NotifyString string;/* [case(2)] */ - struct spoolss_DeviceMode *devmode;/* [unique,case(3)] */ + struct spoolss_DevmodeContainer devmode;/* [case(3)] */ struct spoolss_TimeCtr time;/* [case(4)] */ struct sec_desc_buf sd;/* [case(5)] */ }/* [switch_type(uint32)] */; -- cgit From dc0bf17ac130764f3bbdc2d07de4a0fb54a761d2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 10:29:46 +0100 Subject: s3-rpcclient: use correct clientname in spoolss_RemoteFindFirstPrinterChangeNotifyEx command. Guenther --- source3/rpcclient/cmd_spoolss.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 944bac7731..bb9d0e6d6c 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -2526,6 +2526,7 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, const char **argv) { const char *printername; + const char *clientname; POLICY_HND hnd; bool got_hnd = False; WERROR result; @@ -2582,13 +2583,19 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, } option.types[1].fields[0] = JOB_NOTIFY_PRINTER_NAME; + clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname()); + if (!clientname) { + result = WERR_NOMEM; + goto done; + } + /* Send rffpcnex */ status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx, &hnd, 0, 0, - cli->srv_name_slash, + clientname, 123, &option, &result); -- cgit From 00913a73c7c93f410e5e05a1825138a61705ea6e Mon Sep 17 00:00:00 2001 From: Bjƶrn Jacke Date: Sun, 22 Feb 2009 19:46:40 +0100 Subject: prefer gssapi header files from subdirectory this fixes some compile time noise on FreeBSD 7 --- source3/include/includes.h | 6 +++--- source3/libaddns/dns.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index 1906830d48..5ab5564e47 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -190,12 +190,12 @@ typedef int ber_int_t; #undef HAVE_LDAP #endif -#if HAVE_GSSAPI_H -#include -#elif HAVE_GSSAPI_GSSAPI_H +#if HAVE_GSSAPI_GSSAPI_H #include #elif HAVE_GSSAPI_GSSAPI_GENERIC_H #include +#elif HAVE_GSSAPI_H +#include #endif #if HAVE_COM_ERR_H diff --git a/source3/libaddns/dns.h b/source3/libaddns/dns.h index 42662a224b..57a9b6a002 100644 --- a/source3/libaddns/dns.h +++ b/source3/libaddns/dns.h @@ -81,12 +81,12 @@ #include #endif -#if HAVE_GSSAPI_H -#include -#elif HAVE_GSSAPI_GSSAPI_H +#if HAVE_GSSAPI_GSSAPI_H #include #elif HAVE_GSSAPI_GSSAPI_GENERIC_H #include +#elif HAVE_GSSAPI_H +#include #endif #if defined(HAVE_GSSAPI_H) || defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_GSSAPI_GSSAPI_GENERIC_H) -- cgit From 03a15f2381d467c7c4d2f504297f102806847394 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 12 Feb 2009 13:59:28 +0100 Subject: s3-spoolss: use struct spoolss_Notify instead of SPOOL_NOTIFY_INFO_DATA. Guenther --- source3/include/proto.h | 28 +- source3/rpc_server/srv_spoolss_nt.c | 533 +++++++++++------------------------- 2 files changed, 180 insertions(+), 381 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9dc9719e48..fed1dd35fe 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6142,71 +6142,71 @@ WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, cons WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u); WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u); void spoolss_notify_server_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_printer_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_share_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_port_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_driver_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_comment(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_location(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_sepfile(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_print_processor(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_parameters(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_datatype(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_attributes(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); void spoolss_notify_cjobs(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); -void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id); +void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id); WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u); DEVICEMODE *construct_dev_mode(const char *servicename); WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u); diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 0fe66d9ed9..90742d57ae 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -673,43 +673,93 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, return False; } -/* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */ +#define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \ + _data->data.integer[0] = _integer; \ + _data->data.integer[1] = 0; + + +#define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \ + _data->data.string.string = talloc_strdup(mem_ctx, _p); \ + if (!_data->data.string.string) {\ + _data->data.string.size = 0; \ + } \ + _data->data.string.size = strlen_m_term(_p) * 2; + +#define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \ + _data->data.devmode.devmode = _devmode; + +#define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \ + _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \ + if (!_data->data.sd.sd) { \ + _data->data.sd.sd_size = 0; \ + } \ + _data->data.sd.sd_size = _size; + +static void init_systemtime_buffer(TALLOC_CTX *mem_ctx, + struct tm *t, + const char **pp, + uint32_t *plen) +{ + struct spoolss_Time st; + uint32_t len = 16; + char *p; + + if (!init_systemtime(&st, t)) { + return; + } + + p = talloc_array(mem_ctx, char, len); + if (!p) { + return; + } + + /* + * Systemtime must be linearized as a set of UINT16's. + * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au + */ + + SSVAL(p, 0, st.year); + SSVAL(p, 2, st.month); + SSVAL(p, 4, st.day_of_week); + SSVAL(p, 6, st.day); + SSVAL(p, 8, st.hour); + SSVAL(p, 10, st.minute); + SSVAL(p, 12, st.second); + SSVAL(p, 14, st.millisecond); + + *pp = p; + *plen = len; +} + +/* Convert a notification message to a struct spoolss_Notify */ static void notify_one_value(struct spoolss_notify_msg *msg, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0] = msg->notify.value[0]; - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]); } static void notify_string(struct spoolss_notify_msg *msg, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, TALLOC_CTX *mem_ctx) { - UNISTR2 unistr; - /* The length of the message includes the trailing \0 */ - init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE); - - data->notify_data.data.length = msg->len * 2; - data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; + data->data.string.size = msg->len * 2; + data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data); + if (!data->data.string.string) { + data->data.string.size = 0; return; } - - memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2); } static void notify_system_time(struct spoolss_notify_msg *msg, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, TALLOC_CTX *mem_ctx) { - SYSTEMTIME systime; - prs_struct ps; + data->data.string.string = NULL; + data->data.string.size = 0; if (msg->len != sizeof(time_t)) { DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n", @@ -717,42 +767,15 @@ static void notify_system_time(struct spoolss_notify_msg *msg, return; } - if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) { - DEBUG(5, ("notify_system_time: prs_init() failed\n")); - return; - } - - if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) { - DEBUG(5, ("notify_system_time: unable to make systemtime\n")); - prs_mem_free(&ps); - return; - } - - if (!spoolss_io_system_time("", &ps, 0, &systime)) { - prs_mem_free(&ps); - return; - } - - data->notify_data.data.length = prs_offset(&ps); - if (prs_offset(&ps)) { - data->notify_data.data.string = (uint16 *) - TALLOC(mem_ctx, prs_offset(&ps)); - if (!data->notify_data.data.string) { - prs_mem_free(&ps); - return; - } - prs_copy_all_data_out((char *)data->notify_data.data.string, &ps); - } else { - data->notify_data.data.string = NULL; - } - - prs_mem_free(&ps); + init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data), + &data->data.string.string, + &data->data.string.size); } struct notify2_message_table { const char *name; void (*fn)(struct spoolss_notify_msg *msg, - SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx); + struct spoolss_Notify *data, TALLOC_CTX *mem_ctx); }; static struct notify2_message_table printer_notify_table[] = { @@ -966,9 +989,9 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) /* loop over all printers */ for (p = printers_list; p; p = p->next) { - SPOOL_NOTIFY_INFO_DATA *data; - uint32 data_len = 0; - uint32 id; + struct spoolss_Notify *notifies; + uint32_t count = 0; + uint32_t id; int i; /* Is there notification on this handle? */ @@ -989,13 +1012,11 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) /* allocate the max entries possible */ - data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs); - if (!data) { + notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs); + if (!notifies) { return; } - ZERO_STRUCTP(data); - /* build the array of change notifications */ sending_msg_count = 0; @@ -1044,17 +1065,17 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) } } - construct_info_data( &data[data_len], msg->type, msg->field, id ); + construct_info_data( ¬ifies[count], msg->type, msg->field, id ); switch(msg->type) { case PRINTER_NOTIFY_TYPE: if ( printer_notify_table[msg->field].fn ) - printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx); + printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx); break; case JOB_NOTIFY_TYPE: if ( job_notify_table[msg->field].fn ) - job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx); + job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx); break; default: @@ -1062,7 +1083,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) goto done; } - data_len++; + count++; } if ( sending_msg_count ) { @@ -2901,25 +2922,12 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE ********************************************************************/ void spoolss_notify_server_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername); } /******************************************************************* @@ -2927,14 +2935,11 @@ void spoolss_notify_server_name(int snum, ********************************************************************/ void spoolss_notify_printer_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - /* the notify name should not contain the \\server\ part */ char *p = strrchr(printer->info_2->printername, '\\'); @@ -2944,17 +2949,7 @@ void spoolss_notify_printer_name(int snum, p++; } - len = rpcstr_push_talloc(mem_ctx, &temp, p); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p); } /******************************************************************* @@ -2962,26 +2957,12 @@ void spoolss_notify_printer_name(int snum, ********************************************************************/ void spoolss_notify_share_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum)); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } - + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum)); } /******************************************************************* @@ -2989,27 +2970,12 @@ void spoolss_notify_share_name(int snum, ********************************************************************/ void spoolss_notify_port_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - /* even if it's strange, that's consistant in all the code */ - - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname); } /******************************************************************* @@ -3018,25 +2984,12 @@ void spoolss_notify_port_name(int snum, ********************************************************************/ void spoolss_notify_driver_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername); } /******************************************************************* @@ -3044,28 +2997,20 @@ void spoolss_notify_driver_name(int snum, ********************************************************************/ void spoolss_notify_comment(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - if (*printer->info_2->comment == '\0') - len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum)); - else - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment); + char *p; - if (len == (uint32)-1) { - len = 0; - } - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; + if (*printer->info_2->comment == '\0') { + p = lp_comment(snum); } else { - data->notify_data.data.string = NULL; + p = printer->info_2->comment; } + + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment); } /******************************************************************* @@ -3074,25 +3019,12 @@ void spoolss_notify_comment(int snum, ********************************************************************/ void spoolss_notify_location(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location); } /******************************************************************* @@ -3101,14 +3033,13 @@ void spoolss_notify_location(int snum, ********************************************************************/ static void spoolss_notify_devmode(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { /* for a dummy implementation we have to zero the fields */ - data->notify_data.data.length = 0; - data->notify_data.data.string = NULL; + SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL); } /******************************************************************* @@ -3116,25 +3047,12 @@ static void spoolss_notify_devmode(int snum, ********************************************************************/ void spoolss_notify_sepfile(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile); } /******************************************************************* @@ -3143,25 +3061,12 @@ void spoolss_notify_sepfile(int snum, ********************************************************************/ void spoolss_notify_print_processor(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor); } /******************************************************************* @@ -3170,25 +3075,12 @@ void spoolss_notify_print_processor(int snum, ********************************************************************/ void spoolss_notify_parameters(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters); } /******************************************************************* @@ -3197,25 +3089,12 @@ void spoolss_notify_parameters(int snum, ********************************************************************/ void spoolss_notify_datatype(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype); } /******************************************************************* @@ -3225,13 +3104,14 @@ void spoolss_notify_datatype(int snum, ********************************************************************/ static void spoolss_notify_security_desc(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size; - data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ; + SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, + printer->info_2->secdesc_buf->sd_size, + printer->info_2->secdesc_buf->sd); } /******************************************************************* @@ -3240,13 +3120,12 @@ static void spoolss_notify_security_desc(int snum, ********************************************************************/ void spoolss_notify_attributes(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0] = printer->info_2->attributes; - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes); } /******************************************************************* @@ -3254,13 +3133,12 @@ void spoolss_notify_attributes(int snum, ********************************************************************/ static void spoolss_notify_priority(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0] = printer->info_2->priority; - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority); } /******************************************************************* @@ -3268,13 +3146,12 @@ static void spoolss_notify_priority(int snum, ********************************************************************/ static void spoolss_notify_default_priority(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0] = printer->info_2->default_priority; - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority); } /******************************************************************* @@ -3282,13 +3159,12 @@ static void spoolss_notify_default_priority(int snum, ********************************************************************/ static void spoolss_notify_start_time(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0] = printer->info_2->starttime; - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime); } /******************************************************************* @@ -3296,13 +3172,12 @@ static void spoolss_notify_start_time(int snum, ********************************************************************/ static void spoolss_notify_until_time(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0] = printer->info_2->untiltime; - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime); } /******************************************************************* @@ -3310,7 +3185,7 @@ static void spoolss_notify_until_time(int snum, ********************************************************************/ static void spoolss_notify_status(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) @@ -3318,8 +3193,7 @@ static void spoolss_notify_status(int snum, print_status_struct status; print_queue_length(snum, &status); - data->notify_data.value[0]=(uint32) status.status; - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status); } /******************************************************************* @@ -3327,13 +3201,12 @@ static void spoolss_notify_status(int snum, ********************************************************************/ void spoolss_notify_cjobs(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0] = print_queue_length(snum, NULL); - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL)); } /******************************************************************* @@ -3341,15 +3214,14 @@ void spoolss_notify_cjobs(int snum, ********************************************************************/ static void spoolss_notify_average_ppm(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { /* always respond 8 pages per minutes */ /* a little hard ! */ - data->notify_data.value[0] = printer->info_2->averageppm; - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm); } /******************************************************************* @@ -3357,25 +3229,12 @@ static void spoolss_notify_average_ppm(int snum, ********************************************************************/ static void spoolss_notify_username(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user); } /******************************************************************* @@ -3383,13 +3242,12 @@ static void spoolss_notify_username(int snum, ********************************************************************/ static void spoolss_notify_job_status(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0]=nt_printj_status(queue->status); - data->notify_data.value[1] = 0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status)); } /******************************************************************* @@ -3397,25 +3255,12 @@ static void spoolss_notify_job_status(int snum, ********************************************************************/ static void spoolss_notify_job_name(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - smb_ucs2_t *temp = NULL; - uint32 len; - - len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file); } /******************************************************************* @@ -3423,7 +3268,7 @@ static void spoolss_notify_job_name(int snum, ********************************************************************/ static void spoolss_notify_job_status_string(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) @@ -3433,8 +3278,6 @@ static void spoolss_notify_job_status_string(int snum, */ const char *p = ""; - smb_ucs2_t *temp = NULL; - uint32 len; #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */ p = "unknown"; @@ -3455,17 +3298,7 @@ static void spoolss_notify_job_status_string(int snum, } #endif /* NO LONGER NEEDED. */ - len = rpcstr_push_talloc(mem_ctx, &temp, p); - if (len == (uint32)-1) { - len = 0; - } - - data->notify_data.data.length = len; - if (len) { - data->notify_data.data.string = (uint16 *)temp; - } else { - data->notify_data.data.string = NULL; - } + SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p); } /******************************************************************* @@ -3473,13 +3306,12 @@ static void spoolss_notify_job_status_string(int snum, ********************************************************************/ static void spoolss_notify_job_time(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0]=0x0; - data->notify_data.value[1]=0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0); } /******************************************************************* @@ -3487,39 +3319,37 @@ static void spoolss_notify_job_time(int snum, ********************************************************************/ static void spoolss_notify_job_size(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0]=queue->size; - data->notify_data.value[1]=0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size); } /******************************************************************* * fill a notify_info_data with page info ********************************************************************/ static void spoolss_notify_total_pages(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0]=queue->page_count; - data->notify_data.value[1]=0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count); } /******************************************************************* * fill a notify_info_data with pages printed info. ********************************************************************/ static void spoolss_notify_pages_printed(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0]=0; /* Add code when back-end tracks this */ - data->notify_data.value[1]=0; + /* Add code when back-end tracks this */ + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0); } /******************************************************************* @@ -3527,13 +3357,12 @@ static void spoolss_notify_pages_printed(int snum, ********************************************************************/ static void spoolss_notify_job_position(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - data->notify_data.value[0]=queue->job; - data->notify_data.value[1]=0; + SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job); } /******************************************************************* @@ -3541,44 +3370,18 @@ static void spoolss_notify_job_position(int snum, ********************************************************************/ static void spoolss_notify_submitted_time(int snum, - SPOOL_NOTIFY_INFO_DATA *data, + struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - struct tm *t; - uint32 len; - SYSTEMTIME st; - char *p; - - t=gmtime(&queue->time); - - len = sizeof(SYSTEMTIME); + data->data.string.string = NULL; + data->data.string.size = 0; - data->notify_data.data.length = len; - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); + init_systemtime_buffer(mem_ctx, gmtime(&queue->time), + &data->data.string.string, + &data->data.string.size); - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - make_systemtime(&st, t); - - /* - * Systemtime must be linearized as a set of UINT16's. - * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au - */ - - p = (char *)data->notify_data.data.string; - SSVAL(p, 0, st.year); - SSVAL(p, 2, st.month); - SSVAL(p, 4, st.dayofweek); - SSVAL(p, 6, st.day); - SSVAL(p, 8, st.hour); - SSVAL(p, 10, st.minute); - SSVAL(p, 12, st.second); - SSVAL(p, 14, st.milliseconds); } struct s_notify_info_data_table @@ -3587,7 +3390,7 @@ struct s_notify_info_data_table uint16 field; const char *name; uint32 size; - void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data, + void (*fn) (int snum, struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); }; @@ -3725,16 +3528,12 @@ static bool search_notify(uint16 type, uint16 field, int *value) /**************************************************************************** ****************************************************************************/ -void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id) +void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id) { - info_data->type = type; - info_data->field = field; - info_data->reserved = 0; - - info_data->size = size_of_notify_info_data(type, field); - info_data->enc_type = type_of_notify_info_data(type, field); - - info_data->id = id; + info_data->type = type; + info_data->field = field; + info_data->variable_type = size_of_notify_info_data(type, field); + info_data->job_id = id; } /******************************************************************* @@ -3752,7 +3551,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY uint16 type; uint16 field; - SPOOL_NOTIFY_INFO_DATA *current_data; + struct spoolss_Notify *current_data; NT_PRINTER_INFO_LEVEL *printer = NULL; print_queue_struct *queue=NULL; @@ -3773,7 +3572,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY if (!search_notify(type, field, &j) ) continue; - if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) { + if((info->data=SMB_REALLOC_ARRAY(info->data, struct spoolss_Notify, info->count+1)) == NULL) { DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n")); free_a_printer(&printer, 2); return False; @@ -3813,7 +3612,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, uint16 type; uint16 field; - SPOOL_NOTIFY_INFO_DATA *current_data; + struct spoolss_Notify *current_data; DEBUG(4,("construct_notify_jobs_info\n")); @@ -3829,7 +3628,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, if (!search_notify(type, field, &j) ) continue; - if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) { + if((info->data=SMB_REALLOC_ARRAY(info->data, struct spoolss_Notify, info->count+1)) == NULL) { DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n")); return False; } -- cgit From 6259fac904641cdc191d866e4cd9936cc68df45e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 12 Feb 2009 14:17:53 +0100 Subject: s3-spoolss: use struct spoolss_NotifyInfo instead of SPOOL_NOTIFY_INFO. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 182 +++++++++++++++--------------------- 1 file changed, 76 insertions(+), 106 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 90742d57ae..eb04cadf40 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -3386,10 +3386,10 @@ static void spoolss_notify_submitted_time(int snum, struct s_notify_info_data_table { - uint16 type; - uint16 field; + enum spoolss_NotifyType type; + enum spoolss_Field field; const char *name; - uint32 size; + enum spoolss_NotifyTable variable_type; void (*fn) (int snum, struct spoolss_Notify *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); @@ -3401,86 +3401,71 @@ struct s_notify_info_data_table static const struct s_notify_info_data_table notify_info_data_table[] = { -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size }, { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL }, }; /******************************************************************* - Return the size of info_data structure. + Return the variable_type of info_data structure. ********************************************************************/ -static uint32 size_of_notify_info_data(uint16 type, uint16 field) +static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type, + enum spoolss_Field field) { int i=0; - for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) { - if ( (notify_info_data_table[i].type == type) - && (notify_info_data_table[i].field == field) ) { - switch(notify_info_data_table[i].size) { - case NOTIFY_ONE_VALUE: - case NOTIFY_TWO_VALUE: - return 1; - case NOTIFY_STRING: - return 2; - - /* The only pointer notify data I have seen on - the wire is the submitted time and this has - the notify size set to 4. -tpot */ - - case NOTIFY_POINTER: - return 4; - - case NOTIFY_SECDESC: - return 5; - } + for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) { + if ( (notify_info_data_table[i].type == type) && + (notify_info_data_table[i].field == field) ) { + return notify_info_data_table[i].variable_type; } } @@ -3489,23 +3474,6 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field) return 0; } -/******************************************************************* - Return the type of notify_info_data. -********************************************************************/ - -static uint32 type_of_notify_info_data(uint16 type, uint16 field) -{ - uint32 i=0; - - for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) { - if (notify_info_data_table[i].type == type && - notify_info_data_table[i].field == field) - return notify_info_data_table[i].size; - } - - return 0; -} - /**************************************************************************** ****************************************************************************/ @@ -3532,7 +3500,7 @@ void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 f { info_data->type = type; info_data->field = field; - info_data->variable_type = size_of_notify_info_data(type, field); + info_data->variable_type = variable_type_of_notify_info_data(type, field); info_data->job_id = id; } @@ -3542,7 +3510,7 @@ void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 f * ********************************************************************/ -static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int +static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spoolss_NotifyInfo *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id, TALLOC_CTX *mem_ctx) @@ -3572,13 +3540,13 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY if (!search_notify(type, field, &j) ) continue; - if((info->data=SMB_REALLOC_ARRAY(info->data, struct spoolss_Notify, info->count+1)) == NULL) { + if((info->notifies = SMB_REALLOC_ARRAY(info->notifies, struct spoolss_Notify, info->count+1)) == NULL) { DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n")); free_a_printer(&printer, 2); return False; } - current_data = &info->data[info->count]; + current_data = &info->notifies[info->count]; construct_info_data(current_data, type, field, id); @@ -3602,7 +3570,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY ********************************************************************/ static bool construct_notify_jobs_info(print_queue_struct *queue, - SPOOL_NOTIFY_INFO *info, + struct spoolss_NotifyInfo *info, NT_PRINTER_INFO_LEVEL *printer, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id, @@ -3628,12 +3596,12 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, if (!search_notify(type, field, &j) ) continue; - if((info->data=SMB_REALLOC_ARRAY(info->data, struct spoolss_Notify, info->count+1)) == NULL) { + if((info->notifies = SMB_REALLOC_ARRAY(info->notifies, struct spoolss_Notify, info->count+1)) == NULL) { DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n")); return False; } - current_data=&(info->data[info->count]); + current_data=&(info->notifies[info->count]); construct_info_data(current_data, type, field, id); notify_info_data_table[j].fn(snum, current_data, queue, @@ -3675,7 +3643,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, ********************************************************************/ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, - SPOOL_NOTIFY_INFO *info, + struct spoolss_NotifyInfo *info, TALLOC_CTX *mem_ctx) { int snum; @@ -3691,9 +3659,10 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, return WERR_BADFID; option=Printer->notify.option; - info->version=2; - info->data=NULL; - info->count=0; + + info->version = 2; + info->notifies = NULL; + info->count = 0; /* a bug in xp sp2 rc2 causes it to send a fnpcn request without sending a ffpcn() request first */ @@ -3739,7 +3708,7 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, * ********************************************************************/ -static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info, +static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info, TALLOC_CTX *mem_ctx) { int snum; @@ -3759,9 +3728,10 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY option=Printer->notify.option; id = 0x0; - info->version=2; - info->data=NULL; - info->count=0; + + info->version = 2; + info->notifies = NULL; + info->count = 0; /* a bug in xp sp2 rc2 causes it to send a fnpcn request without sending a ffpcn() request first */ -- cgit From 5116f50eb82c76bac40c558c00db17be6b56f161 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 12 Feb 2009 14:18:28 +0100 Subject: s3-spoolss: use pidl for _spoolss_RouterRefreshPrinterChangeNotify. Guenther --- source3/rpc_server/srv_spoolss.c | 27 +++-------------------- source3/rpc_server/srv_spoolss_nt.c | 44 ++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 47 deletions(-) diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 7bb71ab89f..17dbad6988 100644 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -198,30 +198,9 @@ static bool api_spoolss_rffpcnex(pipes_struct *p) static bool api_spoolss_rfnpcnex(pipes_struct *p) { - SPOOL_Q_RFNPCNEX q_u; - SPOOL_R_RFNPCNEX r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if (!spoolss_io_q_rfnpcnex("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_rfnpcnex: unable to unmarshall SPOOL_Q_RFNPCNEX.\n")); - return False; - } - - r_u.status = _spoolss_rfnpcnex(p, &q_u, &r_u); - - if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) { - SAFE_FREE(r_u.info.data); - DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n")); - return False; - } - - SAFE_FREE(r_u.info.data); - - return True; + return proxy_spoolss_call(p, NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY); + /* FIXME */ +// SAFE_FREE(r_u.info.data); } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index eb04cadf40..c351c2fa2b 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -3794,24 +3794,31 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spool return WERR_OK; } -/******************************************************************** - * spoolss_rfnpcnex - ********************************************************************/ +/**************************************************************** + _spoolss_RouterRefreshPrinterChangeNotify +****************************************************************/ -WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u) +WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, + struct spoolss_RouterRefreshPrinterChangeNotify *r) { - POLICY_HND *handle = &q_u->handle; - SPOOL_NOTIFY_INFO *info = &r_u->info; + POLICY_HND *handle = r->in.handle; + struct spoolss_NotifyInfo *info; Printer_entry *Printer=find_printer_index_by_hnd(p, handle); WERROR result = WERR_BADFID; - /* we always have a NOTIFY_INFO struct */ - r_u->info_ptr=0x1; + /* we always have a spoolss_NotifyInfo struct */ + info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo); + if (!info) { + result = WERR_NOMEM; + goto done; + } + + *r->out.info = info; if (!Printer) { - DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n", - OUR_HANDLE(handle))); + DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: " + "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); goto done; } @@ -3830,8 +3837,10 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN Printer->notify.fnpcn = True; if (Printer->notify.client_connected) { - DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change)); - Printer->notify.change = q_u->change; + DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: " + "Saving change value in request [%x]\n", + r->in.change_low)); + Printer->notify.change = r->in.change_low; } /* just ignore the SPOOL_NOTIFY_OPTION */ @@ -10552,17 +10561,6 @@ WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p, return WERR_NOT_SUPPORTED; } -/**************************************************************** - _dcesrv_spoolss_RouterRefreshPrinterChangeNotify -****************************************************************/ - -WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, - struct spoolss_RouterRefreshPrinterChangeNotify *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - /**************************************************************** _spoolss_44 ****************************************************************/ -- cgit From 9af13015b256e5b0eec74e1c788c13e246cde850 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 12 Feb 2009 00:40:37 +0100 Subject: s3-spoolss: use rpccli_spoolss_RouterReplyPrinterEx. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 38 +++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index c351c2fa2b..b27680ca1c 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -1087,8 +1087,42 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) } if ( sending_msg_count ) { - rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd, - data_len, data, p->notify.change, 0 ); + NTSTATUS status; + WERROR werr; + union spoolss_ReplyPrinterInfo info; + struct spoolss_NotifyInfo info0; + uint32_t reply_result; + + info0.version = 0x2; + info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED; + info0.count = count; + info0.notifies = notifies; + + info.info0 = &info0; + + status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx, + &p->notify.client_hnd, + p->notify.change, /* color */ + p->notify.flags, + &reply_result, + 0, /* reply_type, must be 0 */ + info, + &werr); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) { + DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n", + notify_cli_pipe->srv_name_slash, + win_errstr(werr))); + } + switch (reply_result) { + case 0: + break; + case PRINTER_NOTIFY_INFO_DISCARDED: + case PRINTER_NOTIFY_INFO_DISCARDNOTED: + case PRINTER_NOTIFY_INFO_COLOR_MISMATCH: + break; + default: + break; + } } } -- cgit From 9b453f9248de2fce117f029240530d199e039ce1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 12 Feb 2009 16:38:13 +0100 Subject: s3-spoolss: fix memleak of spoolss_Notify array in _spoolss_RouterRefreshPrinterChangeNotify. Guenther --- source3/rpc_server/srv_spoolss.c | 2 -- source3/rpc_server/srv_spoolss_nt.c | 10 ++++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 17dbad6988..cfe3c994e5 100644 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -199,8 +199,6 @@ static bool api_spoolss_rffpcnex(pipes_struct *p) static bool api_spoolss_rfnpcnex(pipes_struct *p) { return proxy_spoolss_call(p, NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY); - /* FIXME */ -// SAFE_FREE(r_u.info.data); } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index b27680ca1c..a3daa7f372 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -3574,7 +3574,10 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spool if (!search_notify(type, field, &j) ) continue; - if((info->notifies = SMB_REALLOC_ARRAY(info->notifies, struct spoolss_Notify, info->count+1)) == NULL) { + info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies, + struct spoolss_Notify, + info->count + 1); + if (info->notifies == NULL) { DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n")); free_a_printer(&printer, 2); return False; @@ -3630,7 +3633,10 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, if (!search_notify(type, field, &j) ) continue; - if((info->notifies = SMB_REALLOC_ARRAY(info->notifies, struct spoolss_Notify, info->count+1)) == NULL) { + info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies, + struct spoolss_Notify, + info->count + 1); + if (info->notifies == NULL) { DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n")); return False; } -- cgit From 418691c2e7eae156b10ae29cf443e26cede92e93 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 13 Feb 2009 12:47:32 +0100 Subject: s3-spoolss: use more idl types in spoolss server. Guenther --- source3/include/proto.h | 5 ++++- source3/rpc_server/srv_spoolss_nt.c | 24 ++++++++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index fed1dd35fe..93b4ca8c7d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6206,8 +6206,11 @@ void spoolss_notify_cjobs(int snum, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); -void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id); WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u); +void construct_info_data(struct spoolss_Notify *info_data, + enum spoolss_NotifyType type, + enum spoolss_Field field, + int id); DEVICEMODE *construct_dev_mode(const char *servicename); WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u); WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u); diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index a3daa7f372..33f139676c 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -3511,7 +3511,9 @@ static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type, /**************************************************************************** ****************************************************************************/ -static bool search_notify(uint16 type, uint16 field, int *value) +static bool search_notify(enum spoolss_NotifyType type, + enum spoolss_Field field, + int *value) { int i; @@ -3530,7 +3532,10 @@ static bool search_notify(uint16 type, uint16 field, int *value) /**************************************************************************** ****************************************************************************/ -void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id) +void construct_info_data(struct spoolss_Notify *info_data, + enum spoolss_NotifyType type, + enum spoolss_Field field, + int id) { info_data->type = type; info_data->field = field; @@ -3550,17 +3555,17 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spool TALLOC_CTX *mem_ctx) { int field_num,j; - uint16 type; - uint16 field; + enum spoolss_NotifyType type; + enum spoolss_Field field; struct spoolss_Notify *current_data; NT_PRINTER_INFO_LEVEL *printer = NULL; print_queue_struct *queue=NULL; - type=option_type->type; + type = option_type->type; DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n", - (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"), + (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"), option_type->count, lp_servicename(snum))); if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum)))) @@ -3614,9 +3619,8 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, TALLOC_CTX *mem_ctx) { int field_num,j; - uint16 type; - uint16 field; - + enum spoolss_NotifyType type; + enum spoolss_Field field; struct spoolss_Notify *current_data; DEBUG(4,("construct_notify_jobs_info\n")); @@ -3624,7 +3628,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, type = option_type->type; DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n", - (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"), + (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"), option_type->count)); for(field_num=0; field_numcount; field_num++) { -- cgit From 2efa7cf6d9b20fe20a2bd6b0e64625c5082f97f1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 13:06:04 +0100 Subject: s3-spoolss: add dup_spoolss_NotifyOption. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 33f139676c..4b7d42df54 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -2885,6 +2885,57 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer, return (W_ERROR_IS_OK(result)); } +/**************************************************************** + ****************************************************************/ + +static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx, + const struct spoolss_NotifyOption *r) +{ + struct spoolss_NotifyOption *option; + uint32_t i,k; + + if (!r) { + return NULL; + } + + option = talloc_zero(mem_ctx, struct spoolss_NotifyOption); + if (!option) { + return NULL; + } + + *option = *r; + + if (!option->count) { + return option; + } + + option->types = talloc_zero_array(option, + struct spoolss_NotifyOptionType, option->count); + if (!option->types) { + talloc_free(option); + return NULL; + } + + for (i=0; i < option->count; i++) { + option->types[i] = r->types[i]; + + if (option->types[i].count) { + option->types[i].fields = talloc_zero_array(option, + enum spoolss_Field, option->types[i].count); + if (!option->types[i].fields) { + talloc_free(option); + return NULL; + } + for (k=0; ktypes[i].count; k++) { + option->types[i].fields[k] = + r->types[i].fields[k]; + } + } + } + + return option; +} + /******************************************************************** * _spoolss_rffpcnex * ReplyFindFirstPrinterChangeNotifyEx -- cgit From b3f6d6910850efaf6240dd01576d3794d8aec170 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Feb 2009 00:12:21 +0100 Subject: s3-spoolss: use spoolss_NotifyOption and spoolss_NotifyType instead of SPOOL_NOTIFY_OPTION and SPOOL_NOTIFY_OPTION_TYPE. Guenther --- source3/include/nt_printing.h | 2 +- source3/rpc_server/srv_spoolss_nt.c | 105 +++++++++++------------------------- 2 files changed, 32 insertions(+), 75 deletions(-) diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index 3bf51f2c9d..43fd363b55 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -439,7 +439,7 @@ typedef struct _Printer{ uint32 options; fstring localmachine; uint32 printerlocal; - SPOOL_NOTIFY_OPTION *option; + struct spoolss_NotifyOption *option; POLICY_HND client_hnd; bool client_connected; uint32 change; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 4b7d42df54..97ce109e7f 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -130,19 +130,6 @@ static int nt_printq_status(int v) return 0; } -/**************************************************************************** - Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry. -****************************************************************************/ - -static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp) -{ - if (*pp == NULL) - return; - - SAFE_FREE((*pp)->ctr.type); - SAFE_FREE(*pp); -} - /*************************************************************************** Disconnect from the client ****************************************************************************/ @@ -215,8 +202,7 @@ static int printer_entry_destructor(Printer_entry *Printer) Printer->notify.options=0; Printer->notify.localmachine[0]='\0'; Printer->notify.printerlocal=0; - free_spool_notify_option(&Printer->notify.option); - Printer->notify.option=NULL; + TALLOC_FREE(Printer->notify.option); Printer->notify.client_connected=False; free_nt_devicemode( &Printer->nt_devmode ); @@ -227,35 +213,6 @@ static int printer_entry_destructor(Printer_entry *Printer) return 0; } -/**************************************************************************** - Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry. -****************************************************************************/ - -static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp) -{ - SPOOL_NOTIFY_OPTION *new_sp = NULL; - - if (!sp) - return NULL; - - new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION); - if (!new_sp) - return NULL; - - *new_sp = *sp; - - if (sp->ctr.count) { - new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count); - - if (!new_sp->ctr.type) { - SAFE_FREE(new_sp); - return NULL; - } - } - - return new_sp; -} - /**************************************************************************** find printer index by handle ****************************************************************************/ @@ -633,7 +590,7 @@ static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type, static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, uint16 notify_field) { - SPOOL_NOTIFY_OPTION *option = p->notify.option; + struct spoolss_NotifyOption *option = p->notify.option; uint32 i, j; /* @@ -655,13 +612,13 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, /* Check match for notify_type */ - if (option->ctr.type[i].type != notify_type) + if (option->types[i].type != notify_type) continue; /* Check match for field */ - for (j = 0; j < option->ctr.type[i].count; j++) { - if (option->ctr.type[i].fields[j] == notify_field) { + for (j = 0; j < option->types[i].count; j++) { + if (option->types[i].fields[j] == notify_field) { return True; } } @@ -2971,10 +2928,8 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE Printer->notify.options=options; Printer->notify.printerlocal=printerlocal; - if (Printer->notify.option) - free_spool_notify_option(&Printer->notify.option); - - Printer->notify.option=dup_spool_notify_option(option); + TALLOC_FREE(Printer->notify.option); + Printer->notify.option = dup_spoolss_NotifyOption(Printer, option); unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)); @@ -3600,9 +3555,11 @@ void construct_info_data(struct spoolss_Notify *info_data, * ********************************************************************/ -static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spoolss_NotifyInfo *info, int - snum, SPOOL_NOTIFY_OPTION_TYPE - *option_type, uint32 id, +static bool construct_notify_printer_info(Printer_entry *print_hnd, + struct spoolss_NotifyInfo *info, + int snum, + const struct spoolss_NotifyOptionType *option_type, + uint32_t id, TALLOC_CTX *mem_ctx) { int field_num,j; @@ -3622,7 +3579,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spool if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum)))) return False; - for(field_num=0; field_numcount; field_num++) { + for(field_num=0; field_num < option_type->count; field_num++) { field = option_type->fields[field_num]; DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field)); @@ -3665,8 +3622,9 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spool static bool construct_notify_jobs_info(print_queue_struct *queue, struct spoolss_NotifyInfo *info, NT_PRINTER_INFO_LEVEL *printer, - int snum, SPOOL_NOTIFY_OPTION_TYPE - *option_type, uint32 id, + int snum, + const struct spoolss_NotifyOptionType *option_type, + uint32_t id, TALLOC_CTX *mem_ctx) { int field_num,j; @@ -3745,15 +3703,15 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, Printer_entry *Printer=find_printer_index_by_hnd(p, hnd); int n_services=lp_numservices(); int i; - SPOOL_NOTIFY_OPTION *option; - SPOOL_NOTIFY_OPTION_TYPE *option_type; + struct spoolss_NotifyOption *option; + struct spoolss_NotifyOptionType option_type; DEBUG(4,("printserver_notify_info\n")); if (!Printer) return WERR_BADFID; - option=Printer->notify.option; + option = Printer->notify.option; info->version = 2; info->notifies = NULL; @@ -3766,15 +3724,15 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, return WERR_BADFID; for (i=0; icount; i++) { - option_type=&(option->ctr.type[i]); + option_type = option->types[i]; - if (option_type->type!=PRINTER_NOTIFY_TYPE) + if (option_type.type != PRINTER_NOTIFY_TYPE) continue; for (snum=0; snumnotify.option; + option = Printer->notify.option; id = 0x0; info->version = 2; @@ -3837,12 +3795,12 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spool get_printer_snum(p, hnd, &snum, NULL); for (i=0; icount; i++) { - option_type=&option->ctr.type[i]; + option_type = option->types[i]; - switch ( option_type->type ) { + switch (option_type.type) { case PRINTER_NOTIFY_TYPE: if(construct_notify_printer_info(Printer, info, snum, - option_type, id, + &option_type, id, mem_ctx)) id--; break; @@ -3858,7 +3816,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spool for (j=0; jnotify.change = r->in.change_low; } - /* just ignore the SPOOL_NOTIFY_OPTION */ + /* just ignore the spoolss_NotifyOption */ switch (Printer->printer_type) { case SPLHND_SERVER: @@ -6645,8 +6603,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p, Printer->notify.options=0; Printer->notify.localmachine[0]='\0'; Printer->notify.printerlocal=0; - if (Printer->notify.option) - free_spool_notify_option(&Printer->notify.option); + TALLOC_FREE(Printer->notify.option); Printer->notify.client_connected=False; return WERR_OK; -- cgit From c1e76d0dd9a1a7134fa3c0012a9cbe8f51f0716c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 16 Feb 2009 23:33:10 +0100 Subject: s3-spoolss: use pidl for _spoolss_RemoteFindFirstPrinterChangeNotifyEx. Guenther --- source3/rpc_server/srv_spoolss.c | 22 +------------------- source3/rpc_server/srv_spoolss_nt.c | 41 ++++++++++++------------------------- 2 files changed, 14 insertions(+), 49 deletions(-) diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index cfe3c994e5..ee36f04c6d 100644 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -161,27 +161,7 @@ static bool api_spoolss_deleteprinterdriver(pipes_struct *p) static bool api_spoolss_rffpcnex(pipes_struct *p) { - SPOOL_Q_RFFPCNEX q_u; - SPOOL_R_RFFPCNEX r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if (!spoolss_io_q_rffpcnex("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_rffpcnex: unable to unmarshall SPOOL_Q_RFFPCNEX.\n")); - return False; - } - - r_u.status = _spoolss_rffpcnex(p, &q_u, &r_u); - - if (!spoolss_io_r_rffpcnex("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_rffpcnex: unable to marshall SPOOL_R_RFFPCNEX.\n")); - return False; - } - - return True; + return proxy_spoolss_call(p, NDR_SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFYEX); } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 97ce109e7f..a4679eb717 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -2893,26 +2893,22 @@ static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx return option; } -/******************************************************************** - * _spoolss_rffpcnex - * ReplyFindFirstPrinterChangeNotifyEx +/**************************************************************** + * _spoolss_RemoteFindFirstPrinterChangeNotifyEx * * before replying OK: status=0 a rpc call is made to the workstation * asking ReplyOpenPrinter * * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe * called from api_spoolss_rffpcnex - ********************************************************************/ +****************************************************************/ -WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u) +WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, + struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r) { - POLICY_HND *handle = &q_u->handle; - uint32 flags = q_u->flags; - uint32 options = q_u->options; - UNISTR2 *localmachine = &q_u->localmachine; - uint32 printerlocal = q_u->printerlocal; + POLICY_HND *handle = r->in.handle; int snum = -1; - SPOOL_NOTIFY_OPTION *option = q_u->option; + struct spoolss_NotifyOption *option = r->in.notify_options; struct sockaddr_storage client_ss; /* store the notify value in the printer struct */ @@ -2920,19 +2916,19 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE Printer_entry *Printer=find_printer_index_by_hnd(p, handle); if (!Printer) { - DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); + DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: " + "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); return WERR_BADFID; } - Printer->notify.flags=flags; - Printer->notify.options=options; - Printer->notify.printerlocal=printerlocal; + Printer->notify.flags = r->in.flags; + Printer->notify.options = r->in.options; + Printer->notify.printerlocal = r->in.printer_local; TALLOC_FREE(Printer->notify.option); Printer->notify.option = dup_spoolss_NotifyOption(Printer, option); - unistr2_to_ascii(Printer->notify.localmachine, localmachine, - sizeof(Printer->notify.localmachine)); + fstrcpy(Printer->notify.localmachine, r->in.local_machine); /* Connect to the client machine and send a ReplyOpenPrinter */ @@ -10591,17 +10587,6 @@ WERROR _spoolss_ResetPrinterEx(pipes_struct *p, return WERR_NOT_SUPPORTED; } -/**************************************************************** - _spoolss_RemoteFindFirstPrinterChangeNotifyEx -****************************************************************/ - -WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, - struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - /**************************************************************** _spoolss_RouterReplyPrinterEx ****************************************************************/ -- cgit From ce8ca0e68a577d09b492bd226b22e9c61d35ce09 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 12 Feb 2009 16:21:59 +0100 Subject: s3-spoolss: remove old spoolss_RouterRefreshPrinterChangeNotify. Guenther --- source3/include/proto.h | 3 -- source3/include/rpc_spoolss.h | 18 ------------ source3/rpc_parse/parse_spoolss.c | 62 --------------------------------------- 3 files changed, 83 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 93b4ca8c7d..5c28b5947e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5837,8 +5837,6 @@ bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth); bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth); bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth); bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth); bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth); bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth); @@ -6206,7 +6204,6 @@ void spoolss_notify_cjobs(int snum, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); -WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u); void construct_info_data(struct spoolss_Notify *info_data, enum spoolss_NotifyType type, enum spoolss_Field field, diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 670eca4ca4..3c39adc551 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -458,24 +458,6 @@ typedef struct spool_r_rffpcnex } SPOOL_R_RFFPCNEX; -/* Remote Find Next Printer Change Notify Ex */ -typedef struct spool_q_rfnpcnex -{ - POLICY_HND handle; - uint32 change; - uint32 option_ptr; - SPOOL_NOTIFY_OPTION *option; -} -SPOOL_Q_RFNPCNEX; - -typedef struct spool_r_rfnpcnex -{ - uint32 info_ptr; - SPOOL_NOTIFY_INFO info; - WERROR status; -} -SPOOL_R_RFNPCNEX; - typedef struct printer_info_0 { UNISTR printername; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 577ba73a42..abf17eacfb 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -1075,68 +1075,6 @@ bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct * return True; } -/******************************************************************* - * read a structure. - * called from spoolss_q_rfnpcnex (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth)) - return False; - - if(!prs_uint32("change", ps, depth, &q_u->change)) - return False; - - if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr)) - return False; - - if (q_u->option_ptr!=0) { - - if (UNMARSHALLING(ps)) - if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL) - return False; - - if(!smb_io_notify_option("notify option", q_u->option, ps, depth)) - return False; - } - - return True; -} - -/******************************************************************* - * write a structure. - * called from spoolss_r_rfnpcnex (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr)) - return False; - - if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth)) - return False; - - if(!prs_align(ps)) - return False; - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - /******************************************************************* * return the length of a uint16 (obvious, but the code is clean) ********************************************************************/ -- cgit From 0295008a87478a6fa1c685128fa01918102d286d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 12 Feb 2009 14:28:33 +0100 Subject: s3-spoolss: remove old spoolss_RouterReplyPrinterEx. Guenther --- source3/include/proto.h | 9 --- source3/include/rpc_spoolss.h | 19 ------- source3/rpc_client/cli_spoolss_notify.c | 54 ------------------ source3/rpc_parse/parse_spoolss.c | 98 --------------------------------- 4 files changed, 180 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 5c28b5947e..2aad1e54fd 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5524,10 +5524,6 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me /* The following definitions come from rpc_client/cli_spoolss_notify.c */ -WERROR rpccli_spoolss_rrpcn(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 notify_data_len, - SPOOL_NOTIFY_INFO_DATA *notify_data, - uint32 change_low, uint32 change_high); WERROR rpccli_spoolss_rffpcnex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 flags, uint32 options, const char *localmachine, uint32 printerlocal, @@ -5992,11 +5988,6 @@ void free_printer_info_5(PRINTER_INFO_5 *printer); void free_printer_info_6(PRINTER_INFO_6 *printer); void free_printer_info_7(PRINTER_INFO_7 *printer); void free_job_info_2(JOB_INFO_2 *job); -bool make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd, - uint32 change_low, uint32 change_high, - SPOOL_NOTIFY_INFO *info); -bool spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth); bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, POLICY_HND *hnd, const char *key, uint32 size); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 3c39adc551..7f7555fd85 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -1331,25 +1331,6 @@ typedef struct spool_r_getjob } SPOOL_R_GETJOB; -typedef struct spool_q_rrpcn -{ - POLICY_HND handle; - uint32 change_low; - uint32 change_high; - uint32 unknown0; - uint32 unknown1; - uint32 info_ptr; - SPOOL_NOTIFY_INFO info; -} -SPOOL_Q_REPLY_RRPCN; - -typedef struct spool_r_rrpcn -{ - uint32 unknown0; - WERROR status; -} -SPOOL_R_REPLY_RRPCN; - typedef struct spool_q_enumprinterkey { POLICY_HND handle; diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c index 8ae7835c4e..df01029a87 100644 --- a/source3/rpc_client/cli_spoolss_notify.c +++ b/source3/rpc_client/cli_spoolss_notify.c @@ -29,60 +29,6 @@ * back channel. */ -/********************************************************************* - This SPOOLSS_REPLY_RRPCN function is used to send a change - notification event when the registration **did** use - SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor - Also see cli_spoolss_routereplyprinter() - *********************************************************************/ - -WERROR rpccli_spoolss_rrpcn(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 notify_data_len, - SPOOL_NOTIFY_INFO_DATA *notify_data, - uint32 change_low, uint32 change_high) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLY_RRPCN q; - SPOOL_R_REPLY_RRPCN r; - WERROR result = W_ERROR(ERRgeneral); - SPOOL_NOTIFY_INFO notify_info; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - ZERO_STRUCT(notify_info); - - /* Initialise input parameters */ - - notify_info.version = 0x2; - notify_info.flags = 0x00020000; /* ?? */ - notify_info.count = notify_data_len; - notify_info.data = notify_data; - - /* create and send a MSRPC command with api */ - /* store the parameters */ - - make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high, - ¬ify_info); - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_RRPCN, - q, r, - qbuf, rbuf, - spoolss_io_q_reply_rrpcn, - spoolss_io_r_reply_rrpcn, - WERR_GENERAL_FAILURE ); - - if (r.unknown0 == 0x00080000) - DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); - else if ( r.unknown0 != 0x0 ) - DEBUG(8,("cli_spoolss_reply_rrpcn: unknown0 is non-zero [0x%x]\n", r.unknown0)); - - result = r.status; - return result; -} - /********************************************************************* *********************************************************************/ diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index abf17eacfb..828a2f22f9 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -4623,104 +4623,6 @@ static bool copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *sr } #endif /* JERRY */ -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd, - uint32 change_low, uint32 change_high, - SPOOL_NOTIFY_INFO *info) -{ - if (q_u == NULL) - return False; - - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - q_u->change_low=change_low; - q_u->change_high=change_high; - - q_u->unknown0=0x0; - q_u->unknown1=0x0; - - q_u->info_ptr=0x0FF0ADDE; - - q_u->info.version=2; - - if (info->count) { - DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n", - info->count)); - q_u->info.version = info->version; - q_u->info.flags = info->flags; - q_u->info.count = info->count; - /* pointer field - be careful! */ - q_u->info.data = info->data; - } - else { - q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED; - q_u->info.count=0; - } - - return True; -} - -/******************************************************************* - Parse a SPOOL_Q_REPLY_RRPCN structure. -********************************************************************/ - -bool spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth)) - return False; - - if (!prs_uint32("change_low", ps, depth, &q_u->change_low)) - return False; - - if (!prs_uint32("change_high", ps, depth, &q_u->change_high)) - return False; - - if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0)) - return False; - - if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1)) - return False; - - if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr)) - return False; - - if(q_u->info_ptr!=0) - if(!smb_io_notify_info(desc, &q_u->info, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_R_REPLY_RRPCN structure. -********************************************************************/ - -bool spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0)) - return False; - - if (!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - /******************************************************************* * read a structure. ********************************************************************/ -- cgit From fc703a14928c61031589ac6cce8f2985e5fb87a9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 12 Feb 2009 14:33:26 +0100 Subject: s3-spoolss: remove SPOOL_NOTIFY_INFO_DATA and SPOOL_NOTIFY_INFO alltogether. Guenther --- source3/include/proto.h | 2 - source3/include/rpc_spoolss.h | 30 ---- source3/rpc_parse/parse_spoolss.c | 317 -------------------------------------- 3 files changed, 349 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 2aad1e54fd..cf54853a2e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5813,8 +5813,6 @@ bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); -bool smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, - prs_struct *ps, int depth); bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u ); bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode); bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 7f7555fd85..26ecf2bfa5 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -406,36 +406,6 @@ typedef struct spool_notify_option } SPOOL_NOTIFY_OPTION; -typedef struct spool_notify_info_data -{ - uint16 type; - uint16 field; - uint32 reserved; - uint32 id; - union { - uint32 value[2]; - struct { - uint32 length; - uint16 *string; - } data; - struct { - uint32 size; - SEC_DESC *desc; - } sd; - } - notify_data; - uint32 size; - uint32 enc_type; -} SPOOL_NOTIFY_INFO_DATA; - -typedef struct spool_notify_info -{ - uint32 version; - uint32 flags; - uint32 count; - SPOOL_NOTIFY_INFO_DATA *data; -} -SPOOL_NOTIFY_INFO; /* If the struct name looks obscure, yes it is ! */ /* RemoteFindFirstPrinterChangeNotificationEx query struct */ diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 828a2f22f9..89676cbaff 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -200,257 +200,6 @@ static bool smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, return True; } -/******************************************************************* -reads or writes an NOTIFY INFO DATA structure. -********************************************************************/ - -static bool smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth) -{ - uint32 useless_ptr=0x0FF0ADDE; - - prs_debug(ps, depth, desc, "smb_io_notify_info_data"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_uint16("type", ps, depth, &data->type)) - return False; - if(!prs_uint16("field", ps, depth, &data->field)) - return False; - - if(!prs_uint32("how many words", ps, depth, &data->size)) - return False; - if(!prs_uint32("id", ps, depth, &data->id)) - return False; - if(!prs_uint32("how many words", ps, depth, &data->size)) - return False; - - switch (data->enc_type) { - - /* One and two value data has two uint32 values */ - - case NOTIFY_ONE_VALUE: - case NOTIFY_TWO_VALUE: - - if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0])) - return False; - if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1])) - return False; - break; - - /* Pointers and strings have a string length and a - pointer. For a string the length is expressed as - the number of uint16 characters plus a trailing - \0\0. */ - - case NOTIFY_POINTER: - - if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length )) - return False; - if(!prs_uint32("pointer", ps, depth, &useless_ptr)) - return False; - - break; - - case NOTIFY_STRING: - - if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length)) - return False; - - if(!prs_uint32("pointer", ps, depth, &useless_ptr)) - return False; - - break; - - case NOTIFY_SECDESC: - if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) ) - return False; - if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) ) - return False; - - break; - - default: - DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n", - data->enc_type)); - break; - } - - return True; -} - -/******************************************************************* -reads or writes an NOTIFY INFO DATA structure. -********************************************************************/ - -bool smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings"); - depth++; - - if(!prs_align(ps)) - return False; - - switch(data->enc_type) { - - /* No data for values */ - - case NOTIFY_ONE_VALUE: - case NOTIFY_TWO_VALUE: - - break; - - /* Strings start with a length in uint16s */ - - case NOTIFY_STRING: - - if (MARSHALLING(ps)) - data->notify_data.data.length /= 2; - - if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length)) - return False; - - if (UNMARSHALLING(ps) && data->notify_data.data.length) { - data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, - data->notify_data.data.length); - - if (!data->notify_data.data.string) - return False; - } - - if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string, - data->notify_data.data.length)) - return False; - - if (MARSHALLING(ps)) - data->notify_data.data.length *= 2; - - break; - - case NOTIFY_POINTER: - - if (UNMARSHALLING(ps) && data->notify_data.data.length) { - data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, - data->notify_data.data.length); - - if (!data->notify_data.data.string) - return False; - } - - if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length)) - return False; - - break; - - case NOTIFY_SECDESC: - if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) ) - return False; - if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) ) - return False; - break; - - default: - DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n", - data->enc_type)); - break; - } - -#if 0 - if (isvalue==False) { - - /* length of string in unicode include \0 */ - x=data->notify_data.data.length+1; - - if (data->field != 16) - if(!prs_uint32("string length", ps, depth, &x )) - return False; - - if (MARSHALLING(ps)) { - /* These are already in little endian format. Don't byte swap. */ - if (x == 1) { - - /* No memory allocated for this string - therefore following the data.string - pointer is a bad idea. Use a pointer to - the uint32 length union member to - provide a source for a unicode NULL */ - - if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2)) - return False; - } else { - - if (data->field == 16) - x /= 2; - - if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x)) - return False; - } - } else { - - /* Tallocate memory for string */ - - if (x) { - data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2); - if (!data->notify_data.data.string) - return False; - } else { - data->notify_data.data.string = NULL; - } - - if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x)) - return False; - } - } - -#endif - -#if 0 /* JERRY */ - /* Win2k does not seem to put this parse align here */ - if(!prs_align(ps)) - return False; -#endif - - return True; -} - -/******************************************************************* -reads or writes an NOTIFY INFO structure. -********************************************************************/ - -static bool smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth) -{ - int i; - - prs_debug(ps, depth, desc, "smb_io_notify_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("count", ps, depth, &info->count)) - return False; - if(!prs_uint32("version", ps, depth, &info->version)) - return False; - if(!prs_uint32("flags", ps, depth, &info->flags)) - return False; - if(!prs_uint32("count", ps, depth, &info->count)) - return False; - - for (i=0;icount;i++) { - if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth)) - return False; - } - - /* now do the strings at the end of the stream */ - for (i=0;icount;i++) { - if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth)) - return False; - } - - return True; -} - /******************************************************************* ********************************************************************/ @@ -4557,72 +4306,6 @@ void free_job_info_2(JOB_INFO_2 *job) free_devmode(job->devmode); } -#if 0 /* JERRY - not currently used but could be :-) */ - -/******************************************************************* - Deep copy a SPOOL_NOTIFY_INFO_DATA structure - ******************************************************************/ -static bool copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, - SPOOL_NOTIFY_INFO_DATA *src, int n) -{ - int i; - - memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n); - - for (i=0; isize != POINTER) - continue; - len = src->notify_data.data.length; - s = SMB_MALLOC_ARRAY(uint16, len); - if (s == NULL) { - DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n")); - return False; - } - - memcpy(s, src->notify_data.data.string, len*2); - dst->notify_data.data.string = s; - } - - return True; -} - -/******************************************************************* - Deep copy a SPOOL_NOTIFY_INFO structure - ******************************************************************/ -static bool copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src) -{ - if (!dst) { - DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n")); - return False; - } - - dst->version = src->version; - dst->flags = src->flags; - dst->count = src->count; - - if (dst->count) - { - dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count); - - DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n", - dst->count)); - - if (dst->data == NULL) { - DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", - dst->count)); - return False; - } - - return (copy_spool_notify_info_data(dst->data, src->data, src->count)); - } - - return True; -} -#endif /* JERRY */ - /******************************************************************* * read a structure. ********************************************************************/ -- cgit From 2234984fd0a745603b3131e330234349fe428742 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 16 Feb 2009 23:34:12 +0100 Subject: s3-spoolss: remove old spoolss_RemoteFindFirstPrinterChangeNotifyEx. Guenther --- source3/include/proto.h | 11 -- source3/include/rpc_spoolss.h | 22 ---- source3/rpc_client/cli_spoolss_notify.c | 32 ----- source3/rpc_parse/parse_spoolss.c | 219 -------------------------------- 4 files changed, 284 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index cf54853a2e..525cb3c026 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5524,11 +5524,6 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me /* The following definitions come from rpc_client/cli_spoolss_notify.c */ -WERROR rpccli_spoolss_rffpcnex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 flags, uint32 options, - const char *localmachine, uint32 printerlocal, - SPOOL_NOTIFY_OPTION *option); - /* The following definitions come from rpc_client/init_spoolss.c */ bool init_systemtime(struct spoolss_Time *r, @@ -5829,8 +5824,6 @@ bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, const char *valuename, uint32 size); bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth); bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth); bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth); bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth); bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth); @@ -5999,9 +5992,6 @@ bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, uint32 jobid, uint32 level, RPC_BUFFER *buffer, uint32 offered); -bool make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle, - uint32 flags, uint32 options, const char *localmachine, - uint32 printerlocal, SPOOL_NOTIFY_OPTION *option); /* The following definitions come from rpc_server/srv_eventlog_lib.c */ @@ -6127,7 +6117,6 @@ bool convert_devicemode(const char *printername, const DEVICEMODE *devmode, WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, uint32 type, uint8 *data, int real_len ); WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u); -WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u); void spoolss_notify_server_name(int snum, struct spoolss_Notify *data, print_queue_struct *queue, diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 26ecf2bfa5..2d1806aeca 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -406,28 +406,6 @@ typedef struct spool_notify_option } SPOOL_NOTIFY_OPTION; - -/* If the struct name looks obscure, yes it is ! */ -/* RemoteFindFirstPrinterChangeNotificationEx query struct */ -typedef struct spoolss_q_rffpcnex -{ - POLICY_HND handle; - uint32 flags; - uint32 options; - uint32 localmachine_ptr; - UNISTR2 localmachine; - uint32 printerlocal; - uint32 option_ptr; - SPOOL_NOTIFY_OPTION *option; -} -SPOOL_Q_RFFPCNEX; - -typedef struct spool_r_rffpcnex -{ - WERROR status; -} -SPOOL_R_RFFPCNEX; - typedef struct printer_info_0 { UNISTR printername; diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c index df01029a87..41abcd4d0a 100644 --- a/source3/rpc_client/cli_spoolss_notify.c +++ b/source3/rpc_client/cli_spoolss_notify.c @@ -31,35 +31,3 @@ /********************************************************************* *********************************************************************/ - -WERROR rpccli_spoolss_rffpcnex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 flags, uint32 options, - const char *localmachine, uint32 printerlocal, - SPOOL_NOTIFY_OPTION *option) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_RFFPCNEX q; - SPOOL_R_RFFPCNEX r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - make_spoolss_q_rffpcnex( - &q, pol, flags, options, localmachine, printerlocal, - option); - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_RFFPCNEX, - q, r, - qbuf, rbuf, - spoolss_io_q_rffpcnex, - spoolss_io_r_rffpcnex, - WERR_GENERAL_FAILURE ); - - result = r.status; - return result; -} diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 89676cbaff..435bb1bd80 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -70,136 +70,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) return True; } -/******************************************************************* -reads or writes an NOTIFY OPTION TYPE structure. -********************************************************************/ - -/* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one - structure. The _TYPE structure is really the deferred referrants (i.e - the notify fields array) of the _TYPE structure. -tpot */ - -static bool smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "smb_io_notify_option_type"); - depth++; - - if (!prs_align(ps)) - return False; - - if(!prs_uint16("type", ps, depth, &type->type)) - return False; - if(!prs_uint16("reserved0", ps, depth, &type->reserved0)) - return False; - if(!prs_uint32("reserved1", ps, depth, &type->reserved1)) - return False; - if(!prs_uint32("reserved2", ps, depth, &type->reserved2)) - return False; - if(!prs_uint32("count", ps, depth, &type->count)) - return False; - if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr)) - return False; - - return True; -} - -/******************************************************************* -reads or writes an NOTIFY OPTION TYPE DATA. -********************************************************************/ - -static bool smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth) -{ - int i; - - prs_debug(ps, depth, desc, "smb_io_notify_option_type_data"); - depth++; - - /* if there are no fields just return */ - if (type->fields_ptr==0) - return True; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("count2", ps, depth, &type->count2)) - return False; - - if (type->count2 != type->count) - DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2)); - - if (type->count2 > MAX_NOTIFY_TYPE_FOR_NOW) { - return False; - } - - /* parse the option type data */ - for(i=0;icount2;i++) - if(!prs_uint16("fields",ps,depth,&type->fields[i])) - return False; - return True; -} - -/******************************************************************* -reads or writes an NOTIFY OPTION structure. -********************************************************************/ - -static bool smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth) -{ - int i; - - prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr"); - depth++; - - if(!prs_uint32("count", ps, depth, &ctr->count)) - return False; - - /* reading */ - if (UNMARSHALLING(ps) && ctr->count) - if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL) - return False; - - /* the option type struct */ - for(i=0;icount;i++) - if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth)) - return False; - - /* the type associated with the option type struct */ - for(i=0;icount;i++) - if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth)) - return False; - - return True; -} - -/******************************************************************* -reads or writes an NOTIFY OPTION structure. -********************************************************************/ - -static bool smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "smb_io_notify_option"); - depth++; - - if(!prs_uint32("version", ps, depth, &option->version)) - return False; - if(!prs_uint32("flags", ps, depth, &option->flags)) - return False; - if(!prs_uint32("count", ps, depth, &option->count)) - return False; - if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr)) - return False; - - /* marshalling or unmarshalling, that would work */ - if (option->option_type_ptr!=0) { - if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth)) - return False; - } - else { - option->ctr.type=NULL; - option->ctr.count=0; - } - - return True; -} - /******************************************************************* ********************************************************************/ @@ -762,68 +632,6 @@ bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, return True; } -/******************************************************************* - * read a structure. - * called from spoolss_q_rffpcnex (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) - return False; - if(!prs_uint32("flags", ps, depth, &q_u->flags)) - return False; - if(!prs_uint32("options", ps, depth, &q_u->options)) - return False; - if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr)) - return False; - if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal)) - return False; - - if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr)) - return False; - - if (q_u->option_ptr!=0) { - - if (UNMARSHALLING(ps)) - if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL) - return False; - - if(!smb_io_notify_option("notify option", q_u->option, ps, depth)) - return False; - } - - return True; -} - -/******************************************************************* - * write a structure. - * called from spoolss_r_rffpcnex (srv_spoolss.c) - ********************************************************************/ - -bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex"); - depth++; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - /******************************************************************* * return the length of a uint16 (obvious, but the code is clean) ********************************************************************/ @@ -4594,30 +4402,3 @@ bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, return True; } - -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle, - uint32 flags, uint32 options, const char *localmachine, - uint32 printerlocal, SPOOL_NOTIFY_OPTION *option) -{ - memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); - - q_u->flags = flags; - q_u->options = options; - - q_u->localmachine_ptr = 1; - - init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE); - - q_u->printerlocal = printerlocal; - - if (option) - q_u->option_ptr = 1; - - q_u->option = option; - - return True; -} -- cgit From 443743d423f591ce388fff76c60fed23b5494d90 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Feb 2009 00:13:24 +0100 Subject: s3-spoolss: remove old SPOOL_NOTIFY_OPTION definitions. Guenther --- source3/include/rpc_spoolss.h | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 2d1806aeca..504cfea70b 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -343,28 +343,6 @@ PRINTER_DEFAULT; /********************************************/ -typedef struct spool_notify_option_type -{ - uint16 type; - uint16 reserved0; - uint32 reserved1; - uint32 reserved2; - uint32 count; - uint32 fields_ptr; - uint32 count2; - uint16 fields[MAX_NOTIFY_TYPE_FOR_NOW]; -} -SPOOL_NOTIFY_OPTION_TYPE; - -typedef struct spool_notify_option_type_ctr -{ - uint32 count; - SPOOL_NOTIFY_OPTION_TYPE *type; -} -SPOOL_NOTIFY_OPTION_TYPE_CTR; - - - typedef struct s_header_type { uint32 type; @@ -396,16 +374,6 @@ typedef struct spool_r_getprinterdata } SPOOL_R_GETPRINTERDATA; -typedef struct spool_notify_option -{ - uint32 version; - uint32 flags; - uint32 count; - uint32 option_type_ptr; - SPOOL_NOTIFY_OPTION_TYPE_CTR ctr; -} -SPOOL_NOTIFY_OPTION; - typedef struct printer_info_0 { UNISTR printername; -- cgit From fda0158c14b97a54a911bb87ffc0ebb7c5729138 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 16:39:53 +0100 Subject: s3-spoolss: remove cli_spoolss_notify.c completly. All of the spoolss change notify code uses pidl generated functions now. Guenther --- source3/Makefile.in | 2 +- source3/include/proto.h | 2 -- source3/rpc_client/cli_spoolss_notify.c | 33 --------------------------------- 3 files changed, 1 insertion(+), 36 deletions(-) delete mode 100644 source3/rpc_client/cli_spoolss_notify.c diff --git a/source3/Makefile.in b/source3/Makefile.in index d4a849cbc7..7564659dd3 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -465,7 +465,7 @@ RPC_CLIENT_OBJ1 = rpc_client/cli_netlogon.o LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \ $(RPC_CLIENT_OBJ1) rpc_client/cli_reg.o $(RPC_CLIENT_OBJ) \ - rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \ + rpc_client/cli_spoolss.o \ rpc_client/init_spoolss.o \ rpc_client/init_samr.o \ librpc/rpc/dcerpc.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 525cb3c026..faf47d3844 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5522,8 +5522,6 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me POLICY_HND *hnd, const char *keyname, uint16 **keylist, uint32 *len); -/* The following definitions come from rpc_client/cli_spoolss_notify.c */ - /* The following definitions come from rpc_client/init_spoolss.c */ bool init_systemtime(struct spoolss_Time *r, diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c deleted file mode 100644 index 41abcd4d0a..0000000000 --- a/source3/rpc_client/cli_spoolss_notify.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - - Copyright (C) Gerald Carter 2001-2002, - Copyright (C) Tim Potter 2000-2002, - Copyright (C) Andrew Tridgell 1994-2000, - Copyright (C) Jean-Francois Micouleau 1999-2000. - Copyright (C) Jeremy Allison 2005. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/* - * SPOOLSS Client RPC's used by servers as the notification - * back channel. - */ - -/********************************************************************* - *********************************************************************/ -- cgit From 689b8f5bb36a003756ee41787487237eef48cfab Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 22 Feb 2009 01:50:49 -0500 Subject: Make all transactions nested in ldb. The current samba4 code expects this behavior anyway, and given we can only have one transaction active per ldb context this is the only sane model we can support. Fix ldb_tdb transactions, we could return back with an error with neither committing nor canceling the actual tdb transaction in some error paths within the ltdb commit and cancel transaction paths. Added also some debugging to trace what was going on. --- source4/lib/ldb/common/ldb.c | 132 +++++++++++++++++++++----------------- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 2 + 2 files changed, 75 insertions(+), 59 deletions(-) diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 2fb5a8f9be..f1b28b6819 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -34,6 +34,19 @@ #include "ldb_private.h" +static int ldb_context_destructor(void *ptr) +{ + struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context); + + if (ldb->transaction_active) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "A transaction is still active in ldb context [%p]", + ldb); + } + + return 0; +} + /* initialise a ldb context The mem_ctx is required @@ -65,6 +78,8 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) /* TODO: get timeout from options if available there */ ldb->default_timeout = 300; /* set default to 5 minutes */ + talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor); + return ldb; } @@ -242,10 +257,24 @@ void ldb_reset_err_string(struct ldb_context *ldb) /* start a transaction */ -static int ldb_transaction_start_internal(struct ldb_context *ldb) +int ldb_transaction_start(struct ldb_context *ldb) { struct ldb_module *module; int status; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "start ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* explicit transaction active, count nested requests */ + if (ldb->transaction_active) { + ldb->transaction_active++; + return LDB_SUCCESS; + } + + /* start a new transaction */ + ldb->transaction_active++; + FIRST_OP(ldb, start_transaction); ldb_reset_err_string(ldb); @@ -266,10 +295,29 @@ static int ldb_transaction_start_internal(struct ldb_context *ldb) /* commit a transaction */ -static int ldb_transaction_commit_internal(struct ldb_context *ldb) +int ldb_transaction_commit(struct ldb_context *ldb) { struct ldb_module *module; int status; + + ldb->transaction_active--; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "commit ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* commit only when all nested transactions are complete */ + if (ldb->transaction_active > 0) { + return LDB_SUCCESS; + } + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + FIRST_OP(ldb, end_transaction); ldb_reset_err_string(ldb); @@ -290,10 +338,29 @@ static int ldb_transaction_commit_internal(struct ldb_context *ldb) /* cancel a transaction */ -static int ldb_transaction_cancel_internal(struct ldb_context *ldb) +int ldb_transaction_cancel(struct ldb_context *ldb) { struct ldb_module *module; int status; + + ldb->transaction_active--; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "cancel ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* really cancel only if all nested transactions are complete */ + if (ldb->transaction_active > 0) { + return LDB_SUCCESS; + } + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + FIRST_OP(ldb, del_transaction); status = module->ops->del_transaction(module); @@ -309,66 +376,13 @@ static int ldb_transaction_cancel_internal(struct ldb_context *ldb) return status; } -int ldb_transaction_start(struct ldb_context *ldb) -{ - /* disable autotransactions */ - ldb->transaction_active++; - - return ldb_transaction_start_internal(ldb); -} - -int ldb_transaction_commit(struct ldb_context *ldb) -{ - /* renable autotransactions (when we reach 0) */ - if (ldb->transaction_active > 0) - ldb->transaction_active--; - - return ldb_transaction_commit_internal(ldb); -} - -int ldb_transaction_cancel(struct ldb_context *ldb) -{ - /* renable autotransactions (when we reach 0) */ - if (ldb->transaction_active > 0) - ldb->transaction_active--; - - return ldb_transaction_cancel_internal(ldb); -} - -static int ldb_autotransaction_start(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_start_internal(ldb); -} - -static int ldb_autotransaction_commit(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_commit_internal(ldb); -} - -static int ldb_autotransaction_cancel(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_cancel_internal(ldb); -} - /* autostarts a transacion if none active */ static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req) { int ret; - ret = ldb_autotransaction_start(ldb); + ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { return ret; } @@ -379,9 +393,9 @@ static int ldb_autotransaction_request(struct ldb_context *ldb, } if (ret == LDB_SUCCESS) { - return ldb_autotransaction_commit(ldb); + return ldb_transaction_commit(ldb); } - ldb_autotransaction_cancel(ldb); + ldb_transaction_cancel(ldb); if (ldb->err_string == NULL) { /* no error string was setup by the backend */ diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index d6276c4b86..24ec06ea32 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -865,6 +865,7 @@ static int ltdb_end_trans(struct ldb_module *module) ltdb->in_transaction--; if (ltdb_index_transaction_commit(module) != 0) { + tdb_transaction_cancel(ltdb->tdb); return ltdb_err_map(tdb_error(ltdb->tdb)); } @@ -883,6 +884,7 @@ static int ltdb_del_trans(struct ldb_module *module) ltdb->in_transaction--; if (ltdb_index_transaction_cancel(module) != 0) { + tdb_transaction_cancel(ltdb->tdb); return ltdb_err_map(tdb_error(ltdb->tdb)); } -- cgit From ca24822234d9dc77dbe3f351d6dbab5558efac39 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 23 Feb 2009 13:33:39 -0500 Subject: Fix GDB_PROVISION mode --- selftest/target/Samba4.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 7264ddbcb9..09138cf0aa 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -578,7 +578,7 @@ sub provision_raw_prepare($$$$$$$) push (@provision_options, "NSS_WRAPPER_PASSWD=\"$ctx->{nsswrap_passwd}\""); push (@provision_options, "NSS_WRAPPER_GROUP=\"$ctx->{nsswrap_group}\""); if (defined($ENV{GDB_PROVISION})) { - push (@provision_options, "gdb --args python"); + push (@provision_options, "gdb --args"); } if (defined($ENV{VALGRIND_PROVISION})) { push (@provision_options, "valgrind"); -- cgit From cf7539abfb0f6e6956bed7a478e0cda6ab734674 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 23 Feb 2009 13:50:11 -0500 Subject: Make char* parameters const - Use const in function signatures whenever appropriate, to help prevent errant scribbling on users' buffers. smbc_set_credentials() always acted as if its formal parameters were const char *, and changing the formal declaration to specify that should not cause any change to the ABI. It is still allowable to pass a writable buffer to a function which specifies that it will not write to the buffer. I'm making this change only in master. Derrell --- source3/include/libsmbclient.h | 8 ++++---- source3/libsmb/libsmb_context.c | 22 ++++++---------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index 8c642b1794..869aeb6a03 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -2677,11 +2677,11 @@ smbc_version(void); */ void -smbc_set_credentials(char *workgroup, - char *user, - char *password, +smbc_set_credentials(const char *workgroup, + const char *user, + const char *password, smbc_bool use_kerberos, - char *signing_state); + const char *signing_state); /* * Wrapper around smbc_set_credentials. diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index c7c9903b76..4c12d18ab7 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -630,11 +630,11 @@ smbc_version(void) * Set the credentials so DFS will work when following referrals. */ void -smbc_set_credentials(char *workgroup, - char *user, - char *password, +smbc_set_credentials(const char *workgroup, + const char *user, + const char *password, smbc_bool use_kerberos, - char *signing_state) + const char *signing_state) { struct user_auth_info *auth_info; @@ -681,18 +681,8 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, signing_state = "force"; } - /* Using CONST_DISCARD here is ugly, but - * we know that smbc_set_credentials() doesn't - * actually modify the strings, and should have - * been const from the start. We're constrained - * by the ABI here. - */ - - smbc_set_credentials(CONST_DISCARD(char *,workgroup), - CONST_DISCARD(char *,user), - CONST_DISCARD(char *,password), - use_kerberos, - CONST_DISCARD(char *,signing_state)); + smbc_set_credentials(workgroup, user, password, + use_kerberos, signing_state); if (smbc_getOptionFallbackAfterKerberos(context)) { cli_cm_set_fallback_after_kerberos(); -- cgit From 1cd7fe71940b7420dd478321b8368a31ae713917 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 23 Feb 2009 17:35:49 -0500 Subject: Fix headers, ldb_includes.h is a private header, do not reference it from ldb.h --- source4/dsdb/samdb/ldb_modules/config.mk | 4 ++-- source4/dsdb/samdb/ldb_modules/linked_attributes.c | 1 + source4/dsdb/samdb/ldb_modules/objectclass.c | 1 + source4/dsdb/samdb/ldb_modules/ranged_results.c | 1 + source4/dsdb/samdb/ldb_modules/samba3sam.c | 2 +- source4/dsdb/samdb/ldb_modules/update_keytab.c | 1 + source4/dsdb/schema/schema_set.c | 1 + source4/lib/ldb/Makefile.in | 2 +- source4/lib/ldb/common/ldb_modules.c | 5 +---- source4/lib/ldb/include/ldb.h | 14 +++++++++++++- source4/lib/ldb/include/ldb_includes.h | 9 --------- source4/lib/ldb/include/ldb_private.h | 5 +---- source4/lib/ldb/ldb_ildap/ldb_ildap.c | 3 +-- source4/lib/ldb/ldb_ldap/ldb_ldap.c | 1 + source4/lib/ldb/ldb_map/ldb_map.c | 2 -- source4/lib/ldb/ldb_map/ldb_map.h | 2 ++ source4/lib/ldb/ldb_map/ldb_map_inbound.c | 2 -- source4/lib/ldb/ldb_map/ldb_map_outbound.c | 2 -- source4/lib/ldb/ldb_map/ldb_map_private.h | 1 + source4/lib/ldb/ldb_tdb/ldb_index.c | 1 + source4/lib/ldb/ldb_tdb/ldb_tdb.h | 8 +------- source4/lib/ldb/modules/operational.c | 5 +++++ source4/lib/ldb/modules/paged_results.c | 1 + source4/lib/ldb/modules/rdn_name.c | 1 + source4/lib/ldb/tools/cmdline.c | 1 + source4/lib/ldb/tools/ldbedit.c | 2 +- source4/lib/ldb/tools/ldbsearch.c | 1 + source4/lib/ldb/tools/ldbtest.c | 1 + 28 files changed, 42 insertions(+), 38 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 01f5188b6f..583d1dcf04 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -89,7 +89,7 @@ ldb_samldb_OBJ_FILES = \ [MODULE::ldb_samba3sam] SUBSYSTEM = LIBLDB INIT_FUNCTION = LDB_MODULE(samba3sam) -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SMBPASSWD \ +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBLDB SMBPASSWD \ NSS_WRAPPER LIBSECURITY NDR_SECURITY # End MODULE ldb_samldb ################################################ @@ -102,7 +102,7 @@ ldb_samba3sam_OBJ_FILES = \ [MODULE::ldb_simple_ldap_map] SUBSYSTEM = LIBLDB INIT_FUNCTION = LDB_MODULE(entryuuid),LDB_MODULE(nsuniqueid) -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBLDB LIBNDR ENABLE = YES ALIASES = entryuuid nsuniqueid # End MODULE ldb_entryuuid diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c index 2365a58f78..4e28c8a149 100644 --- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c +++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c @@ -30,6 +30,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" struct la_op_store { diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 0261bb32e9..898d913965 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -35,6 +35,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_security.h" diff --git a/source4/dsdb/samdb/ldb_modules/ranged_results.c b/source4/dsdb/samdb/ldb_modules/ranged_results.c index 8f36baa7d6..5ce69a26a2 100644 --- a/source4/dsdb/samdb/ldb_modules/ranged_results.c +++ b/source4/dsdb/samdb/ldb_modules/ranged_results.c @@ -29,6 +29,7 @@ * Author: Andrew Bartlett */ +#include "includes.h" #include "ldb_module.h" struct rr_context { diff --git a/source4/dsdb/samdb/ldb_modules/samba3sam.c b/source4/dsdb/samdb/ldb_modules/samba3sam.c index 3f10748085..59cb9de717 100644 --- a/source4/dsdb/samdb/ldb_modules/samba3sam.c +++ b/source4/dsdb/samdb/ldb_modules/samba3sam.c @@ -6,7 +6,7 @@ */ #include "includes.h" -#include "ldb/include/ldb_module.h" +#include "ldb_module.h" #include "ldb/ldb_map/ldb_map.h" #include "system/passwd.h" diff --git a/source4/dsdb/samdb/ldb_modules/update_keytab.c b/source4/dsdb/samdb/ldb_modules/update_keytab.c index 8920afee71..f1b6863cdb 100644 --- a/source4/dsdb/samdb/ldb_modules/update_keytab.c +++ b/source4/dsdb/samdb/ldb_modules/update_keytab.c @@ -29,6 +29,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_krb5.h" #include "system/kerberos.h" diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index d6b3e40e1a..6abd8a8f88 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" #include "lib/ldb/include/ldb_module.h" #include "param/param.h" diff --git a/source4/lib/ldb/Makefile.in b/source4/lib/ldb/Makefile.in index 7f00e8ebee..663dea9f80 100644 --- a/source4/lib/ldb/Makefile.in +++ b/source4/lib/ldb/Makefile.in @@ -67,7 +67,7 @@ MDLD_FLAGS = @MDLD_FLAGS@ OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(TEVENT_OBJ) $(TALLOC_OBJ) $(POPT_OBJ) $(LDB_MAP_OBJ) @LIBREPLACEOBJ@ $(EXTRA_OBJ) -headers = $(srcdir)/include/ldb.h $(srcdir)/include/ldb_errors.h $(srcdir)/include/ldb_handlers.h $(srcdir)/include/ldb_includes.h $(srcdir)/include/ldb_module.h +headers = $(srcdir)/include/ldb.h $(srcdir)/include/ldb_errors.h $(srcdir)/include/ldb_handlers.h $(srcdir)/include/ldb_module.h BINS = bin/ldbadd bin/ldbsearch bin/ldbdel bin/ldbmodify bin/ldbedit bin/ldbrename bin/ldbtest diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 99a47767e1..ae97ef4cce 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -32,10 +32,7 @@ */ #include "ldb_private.h" - -#if (_SAMBA_BUILD_ >= 4) -#include "includes.h" -#endif +#include "dlinklist.h" #define LDB_MODULE_PREFIX "modules:" #define LDB_MODULE_PREFIX_LEN 8 diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 6990397a74..eb8e0ed11e 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -46,7 +46,19 @@ #define _LDB_H_ 1 /*! \endcond */ -#include "ldb_includes.h" +#ifndef bool +typedef int bool; +#endif +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif + +#include "talloc.h" +#include "tevent.h" +#include "ldb_errors.h" /* major restrictions as compared to normal LDAP: diff --git a/source4/lib/ldb/include/ldb_includes.h b/source4/lib/ldb/include/ldb_includes.h index a2927139c8..602bbec32c 100644 --- a/source4/lib/ldb/include/ldb_includes.h +++ b/source4/lib/ldb/include/ldb_includes.h @@ -4,11 +4,6 @@ a temporary includes file until I work on the ldb build system */ -#if (_SAMBA_BUILD_ >= 4) -/* tell ldb we have the internal ldap code */ -#define HAVE_ILDAP 1 -#endif - #if (_SAMBA_BUILD_ <= 3) /* allow forbidden string functions - should be replaced with _m functions */ #undef strcasecmp @@ -19,9 +14,5 @@ #include "replace.h" #include "system/filesys.h" #include "system/time.h" -#include -#include -#include "ldb_errors.h" -#include "dlinklist.h" #endif /*_LDB_PRIVATE_INCLUDES_H_*/ diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 1ce9e9ecfd..2e8da9941c 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -37,6 +37,7 @@ #ifndef _LDB_PRIVATE_H_ #define _LDB_PRIVATE_H_ 1 +#include "ldb_includes.h" #include "ldb.h" #include "ldb_module.h" @@ -109,10 +110,6 @@ struct ldb_context { struct tevent_context *ev_ctx; }; -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - /* The following definitions come from lib/ldb/common/ldb.c */ int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[], diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index b134405048..4447d0e09a 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -40,11 +40,10 @@ * author: Simo Sorce */ - #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" -#include "tevent.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "auth/auth.h" diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index e1fcdb1353..43a01f75a7 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -38,6 +38,7 @@ * author: Simo Sorce */ +#include "ldb_includes.h" #include "ldb_module.h" #define LDAP_DEPRECATED 1 diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c index ea2bfd1dc1..959540374c 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.c +++ b/source4/lib/ldb/ldb_map/ldb_map.c @@ -35,8 +35,6 @@ * Author: Jelmer Vernooij, Martin Kuehl */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map.h b/source4/lib/ldb/ldb_map/ldb_map.h index 872208174e..3c1fe80895 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.h +++ b/source4/lib/ldb/ldb_map/ldb_map.h @@ -26,6 +26,8 @@ #ifndef __LDB_MAP_H__ #define __LDB_MAP_H__ +#include "ldb_module.h" + /* ldb_map is a skeleton LDB module that can be used for any other modules * that need to map attributes. * diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c index e915a5f46a..822dea654e 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c @@ -24,8 +24,6 @@ */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c index 327fa92f8d..eb7b4590ba 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c @@ -25,8 +25,6 @@ */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_private.h b/source4/lib/ldb/ldb_map/ldb_map_private.h index 0c46443253..612d215ae9 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_private.h +++ b/source4/lib/ldb/ldb_map/ldb_map_private.h @@ -1,3 +1,4 @@ +#include "ldb_includes.h" /* A handy macro to report Out of Memory conditions */ #define map_oom(module) ldb_set_errstring(ldb_module_get_ctx(module), talloc_asprintf(module, "Out of Memory")); diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index cdbef3944b..ad27c9a9a9 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -32,6 +32,7 @@ */ #include "ldb_tdb.h" +#include "dlinklist.h" /* the idxptr code is a bit unusual. The way it works is to replace diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 7ebf199f6f..0a06cdb1b0 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -1,11 +1,5 @@ -#if (_SAMBA_BUILD_ == 3) -#include "tdb/include/tdb.h" -#else -#include "replace.h" -#include "system/wait.h" +#include "ldb_includes.h" #include "tdb.h" -#endif - #include "ldb_module.h" /* this private structure is used by the ltdb backend in the diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c index d862638389..43b223b52e 100644 --- a/source4/lib/ldb/modules/operational.c +++ b/source4/lib/ldb/modules/operational.c @@ -73,8 +73,13 @@ modifiersName: not supported by w2k3? */ +#include "ldb_includes.h" #include "ldb_module.h" +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) +#endif + /* construct a canonical name from a message */ diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c index 7d7cdf66a0..2a06c5e6c5 100644 --- a/source4/lib/ldb/modules/paged_results.c +++ b/source4/lib/ldb/modules/paged_results.c @@ -32,6 +32,7 @@ * Author: Simo Sorce */ +#include "ldb_includes.h" #include "ldb_module.h" struct message_store { diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index a5ffcc034a..880678d89d 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -36,6 +36,7 @@ * Simo Sorce Mar 2006 */ +#include "ldb_includes.h" #include "ldb_module.h" struct rename_context { diff --git a/source4/lib/ldb/tools/cmdline.c b/source4/lib/ldb/tools/cmdline.c index 3dce9b187b..2701de5a48 100644 --- a/source4/lib/ldb/tools/cmdline.c +++ b/source4/lib/ldb/tools/cmdline.c @@ -21,6 +21,7 @@ License along with this library; if not, see . */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index 3a915f8bea..9d3bd27983 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -30,7 +30,7 @@ * * Author: Andrew Tridgell */ - +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c index 35d4ac7002..ba0a2a8927 100644 --- a/source4/lib/ldb/tools/ldbsearch.c +++ b/source4/lib/ldb/tools/ldbsearch.c @@ -31,6 +31,7 @@ * Author: Andrew Tridgell */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index edaa9fb85c..6af0ee9336 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -31,6 +31,7 @@ * Author: Andrew Tridgell */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" -- cgit From 0b62cdbed0867d0712821953700062727f668c65 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Feb 2009 15:03:29 -0800 Subject: Quieten down a boatload of shadowed variable warnings on Solaris. Makes real problems easier to spot. Jeremy. --- librpc/ndr/ndr_sec_helper.c | 8 ++-- source3/modules/nfs4_acls.c | 84 +++++++++++++++++++-------------------- source3/modules/nfs4_acls.h | 10 ++--- source3/registry/reg_dispatcher.c | 8 ++-- 4 files changed, 55 insertions(+), 55 deletions(-) diff --git a/librpc/ndr/ndr_sec_helper.c b/librpc/ndr/ndr_sec_helper.c index 8f84c02f91..62194707c2 100644 --- a/librpc/ndr/ndr_sec_helper.c +++ b/librpc/ndr/ndr_sec_helper.c @@ -91,14 +91,14 @@ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, str /* return the wire size of a security_acl */ -size_t ndr_size_security_acl(const struct security_acl *acl, struct smb_iconv_convenience *ic, int flags) +size_t ndr_size_security_acl(const struct security_acl *theacl, struct smb_iconv_convenience *ic, int flags) { size_t ret; int i; - if (!acl) return 0; + if (!theacl) return 0; ret = 8; - for (i=0;inum_aces;i++) { - ret += ndr_size_security_ace(&acl->aces[i], ic, flags); + for (i=0;inum_aces;i++) { + ret += ndr_size_security_ace(&theacl->aces[i], ic, flags); } return ret; } diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index ba038479af..7756f8f3ab 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -44,10 +44,10 @@ typedef struct _SMB_ACL4_INT_T SMB_ACE4_INT_T *last; } SMB_ACL4_INT_T; -static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *acl) +static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *theacl) { - SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)acl; - if (acl==NULL) + SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)theacl; + if (theacl==NULL) { DEBUG(2, ("acl is NULL\n")); errno = EINVAL; @@ -83,21 +83,21 @@ static SMB_ACE4_INT_T *get_validated_aceint(SMB4ACE_T *ace) SMB4ACL_T *smb_create_smb4acl(void) { TALLOC_CTX *mem_ctx = talloc_tos(); - SMB_ACL4_INT_T *acl = (SMB_ACL4_INT_T *)TALLOC_ZERO_SIZE(mem_ctx, sizeof(SMB_ACL4_INT_T)); - if (acl==NULL) + SMB_ACL4_INT_T *theacl = (SMB_ACL4_INT_T *)TALLOC_ZERO_SIZE(mem_ctx, sizeof(SMB_ACL4_INT_T)); + if (theacl==NULL) { DEBUG(0, ("TALLOC_SIZE failed\n")); errno = ENOMEM; return NULL; } - acl->magic = SMB_ACL4_INT_MAGIC; - /* acl->first, last = NULL not needed */ - return (SMB4ACL_T *)acl; + theacl->magic = SMB_ACL4_INT_MAGIC; + /* theacl->first, last = NULL not needed */ + return (SMB4ACL_T *)theacl; } -SMB4ACE_T *smb_add_ace4(SMB4ACL_T *acl, SMB_ACE4PROP_T *prop) +SMB4ACE_T *smb_add_ace4(SMB4ACL_T *theacl, SMB_ACE4PROP_T *prop) { - SMB_ACL4_INT_T *aclint = get_validated_aclint(acl); + SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl); TALLOC_CTX *mem_ctx = talloc_tos(); SMB_ACE4_INT_T *ace; @@ -143,18 +143,18 @@ SMB4ACE_T *smb_next_ace4(SMB4ACE_T *ace) return (SMB4ACE_T *)aceint->next; } -SMB4ACE_T *smb_first_ace4(SMB4ACL_T *acl) +SMB4ACE_T *smb_first_ace4(SMB4ACL_T *theacl) { - SMB_ACL4_INT_T *aclint = get_validated_aclint(acl); + SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl); if (aclint==NULL) return NULL; return (SMB4ACE_T *)aclint->first; } -uint32 smb_get_naces(SMB4ACL_T *acl) +uint32 smb_get_naces(SMB4ACL_T *theacl) { - SMB_ACL4_INT_T *aclint = get_validated_aclint(acl); + SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl); if (aclint==NULL) return 0; @@ -195,7 +195,7 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf) return 0; } -static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */ +static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *theacl, /* in */ DOM_SID *psid_owner, /* in */ DOM_SID *psid_group, /* in */ bool is_directory, /* in */ @@ -203,15 +203,15 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */ int *pgood_aces /* out */ ) { - SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)acl; + SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)theacl; SMB_ACE4_INT_T *aceint; SEC_ACE *nt_ace_list = NULL; int good_aces = 0; DEBUG(10, ("smbacl_nfs42win entered")); - aclint = get_validated_aclint(acl); - /* We do not check for naces being 0 or acl being NULL here because it is done upstream */ + aclint = get_validated_aclint(theacl); + /* We do not check for naces being 0 or theacl being NULL here because it is done upstream */ /* in smb_get_nt_acl_nfs4(). */ nt_ace_list = (SEC_ACE *)TALLOC_ZERO_SIZE(mem_ctx, aclint->naces * sizeof(SEC_ACE)); if (nt_ace_list==NULL) @@ -275,7 +275,7 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, uint32 security_info, - SEC_DESC **ppdesc, SMB4ACL_T *acl) + SEC_DESC **ppdesc, SMB4ACL_T *theacl) { int good_aces = 0; DOM_SID sid_owner, sid_group; @@ -284,7 +284,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, SEC_ACL *psa = NULL; TALLOC_CTX *mem_ctx = talloc_tos(); - if (acl==NULL || smb_get_naces(acl)==0) + if (theacl==NULL || smb_get_naces(theacl)==0) return NT_STATUS_ACCESS_DENIED; /* special because we * shouldn't alloc 0 for * win */ @@ -292,7 +292,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, uid_to_sid(&sid_owner, sbuf->st_uid); gid_to_sid(&sid_group, sbuf->st_gid); - if (smbacl4_nfs42win(mem_ctx, acl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_mode), + if (smbacl4_nfs42win(mem_ctx, theacl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_mode), &nt_ace_list, &good_aces)==False) { DEBUG(8,("smbacl4_nfs42win failed\n")); return map_nt_error_from_unix(errno); @@ -322,7 +322,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, uint32 security_info, - SEC_DESC **ppdesc, SMB4ACL_T *acl) + SEC_DESC **ppdesc, SMB4ACL_T *theacl) { SMB_STRUCT_STAT sbuf; @@ -332,13 +332,13 @@ NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, return map_nt_error_from_unix(errno); } - return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, acl); + return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, theacl); } NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn, const char *name, uint32 security_info, - SEC_DESC **ppdesc, SMB4ACL_T *acl) + SEC_DESC **ppdesc, SMB4ACL_T *theacl) { SMB_STRUCT_STAT sbuf; @@ -348,7 +348,7 @@ NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn, return map_nt_error_from_unix(errno); } - return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, acl); + return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, theacl); } enum smbacl4_mode_enum {e_simple=0, e_special=1}; @@ -399,9 +399,9 @@ static int smbacl4_get_vfs_params( return 0; } -static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *acl) +static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *theacl) { - SMB_ACL4_INT_T *aclint = get_validated_aclint(acl); + SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl); SMB_ACE4_INT_T *aceint; DEBUG(level, ("NFS4ACL: size=%d\n", aclint->naces)); @@ -423,10 +423,10 @@ static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *acl) * return ace if found matching; otherwise NULL */ static SMB_ACE4PROP_T *smbacl4_find_equal_special( - SMB4ACL_T *acl, + SMB4ACL_T *theacl, SMB_ACE4PROP_T *aceNew) { - SMB_ACL4_INT_T *aclint = get_validated_aclint(acl); + SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl); SMB_ACE4_INT_T *aceint; for(aceint = aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) { @@ -618,14 +618,14 @@ static bool smbacl4_fill_ace4( static int smbacl4_MergeIgnoreReject( enum smbacl4_acedup_enum acedup, - SMB4ACL_T *acl, /* may modify it */ + SMB4ACL_T *theacl, /* may modify it */ SMB_ACE4PROP_T *ace, /* the "new" ACE */ bool *paddNewACE, int i ) { int result = 0; - SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(acl, ace); + SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(theacl, ace); if (ace4found) { switch(acedup) @@ -658,14 +658,14 @@ static SMB4ACL_T *smbacl4_win2nfs4( gid_t ownerGID ) { - SMB4ACL_T *acl; + SMB4ACL_T *theacl; uint32 i; TALLOC_CTX *mem_ctx = talloc_tos(); DEBUG(10, ("smbacl4_win2nfs4 invoked\n")); - acl = smb_create_smb4acl(); - if (acl==NULL) + theacl = smb_create_smb4acl(); + if (theacl==NULL) return NULL; for(i=0; inum_aces; i++) { @@ -682,16 +682,16 @@ static SMB4ACL_T *smbacl4_win2nfs4( } if (pparams->acedup!=e_dontcare) { - if (smbacl4_MergeIgnoreReject(pparams->acedup, acl, + if (smbacl4_MergeIgnoreReject(pparams->acedup, theacl, &ace_v4, &addNewACE, i)) return NULL; } if (addNewACE) - smb_add_ace4(acl, &ace_v4); + smb_add_ace4(theacl, &ace_v4); } - return acl; + return theacl; } NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, @@ -700,7 +700,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, set_nfs4acl_native_fn_t set_nfs4_native) { smbacl4_vfs_params params; - SMB4ACL_T *acl = NULL; + SMB4ACL_T *theacl = NULL; bool result; SMB_STRUCT_STAT sbuf; @@ -759,16 +759,16 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, return NT_STATUS_OK; } - acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms, sbuf.st_uid, sbuf.st_gid); - if (!acl) + theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms, sbuf.st_uid, sbuf.st_gid); + if (!theacl) return map_nt_error_from_unix(errno); - smbacl4_dump_nfs4acl(10, acl); + smbacl4_dump_nfs4acl(10, theacl); if (set_acl_as_root) { become_root(); } - result = set_nfs4_native(fsp, acl); + result = set_nfs4_native(fsp, theacl); saved_errno = errno; if (set_acl_as_root) { unbecome_root(); diff --git a/source3/modules/nfs4_acls.h b/source3/modules/nfs4_acls.h index a227c6e0fc..b2d1196b26 100644 --- a/source3/modules/nfs4_acls.h +++ b/source3/modules/nfs4_acls.h @@ -117,26 +117,26 @@ SMB4ACL_T *smb_create_smb4acl(void); /* prop's contents are copied */ /* it doesn't change the order, appends */ -SMB4ACE_T *smb_add_ace4(SMB4ACL_T *acl, SMB_ACE4PROP_T *prop); +SMB4ACE_T *smb_add_ace4(SMB4ACL_T *theacl, SMB_ACE4PROP_T *prop); SMB_ACE4PROP_T *smb_get_ace4(SMB4ACE_T *ace); /* Returns NULL if none - or error */ -SMB4ACE_T *smb_first_ace4(SMB4ACL_T *acl); +SMB4ACE_T *smb_first_ace4(SMB4ACL_T *theacl); /* Returns NULL in the end - or error */ SMB4ACE_T *smb_next_ace4(SMB4ACE_T *ace); -uint32 smb_get_naces(SMB4ACL_T *acl); +uint32 smb_get_naces(SMB4ACL_T *theacl); NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, uint32 security_info, - SEC_DESC **ppdesc, SMB4ACL_T *acl); + SEC_DESC **ppdesc, SMB4ACL_T *theacl); NTSTATUS smb_get_nt_acl_nfs4(connection_struct *conn, const char *name, uint32 security_info, - SEC_DESC **ppdesc, SMB4ACL_T *acl); + SEC_DESC **ppdesc, SMB4ACL_T *theacl); /* Callback function needed to set the native acl * when applicable */ diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index 7d950c3c4e..c160622054 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -39,7 +39,7 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd) SEC_ACE ace[3]; size_t i = 0; SEC_DESC *sd; - SEC_ACL *acl; + SEC_ACL *theacl; size_t sd_size; /* basic access for Everyone */ @@ -59,14 +59,14 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd) /* create the security descriptor */ - acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace); - if (acl == NULL) { + theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace); + if (theacl == NULL) { return WERR_NOMEM; } sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &global_sid_Builtin_Administrators, - &global_sid_System, NULL, acl, + &global_sid_System, NULL, theacl, &sd_size); if (sd == NULL) { return WERR_NOMEM; -- cgit From 2033b44c3f0872d98d8144a9fbf6d09fbde196e5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Feb 2009 15:44:34 -0800 Subject: More warning fixes for Solaris. Jeremy. --- source3/libgpo/gpo_reg.c | 8 ++++---- source3/modules/vfs_solarisacl.c | 9 +++++---- source3/rpc_server/srv_svcctl_nt.c | 6 +++--- source3/services/services_db.c | 6 +++--- source3/utils/profiles.c | 30 +++++++++++++++--------------- source3/utils/sharesec.c | 6 +++--- 6 files changed, 33 insertions(+), 32 deletions(-) diff --git a/source3/libgpo/gpo_reg.c b/source3/libgpo/gpo_reg.c index 3d385dec14..9367bcae9c 100644 --- a/source3/libgpo/gpo_reg.c +++ b/source3/libgpo/gpo_reg.c @@ -691,7 +691,7 @@ static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx, SEC_ACE ace[6]; uint32_t mask; - SEC_ACL *acl = NULL; + SEC_ACL *theacl = NULL; uint8_t inherit_flags; @@ -735,15 +735,15 @@ static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, inherit_flags); - acl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace); - W_ERROR_HAVE_NO_MEMORY(acl); + theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace); + W_ERROR_HAVE_NO_MEMORY(theacl); *sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_AUTO_INHERITED | /* really ? */ SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */ NULL, NULL, NULL, - acl, sd_size); + theacl, sd_size); W_ERROR_HAVE_NO_MEMORY(*sd); return WERR_OK; diff --git a/source3/modules/vfs_solarisacl.c b/source3/modules/vfs_solarisacl.c index 7bdfe8465b..cafb077555 100644 --- a/source3/modules/vfs_solarisacl.c +++ b/source3/modules/vfs_solarisacl.c @@ -51,11 +51,12 @@ static bool solaris_add_to_acl(SOLARIS_ACL_T *solaris_acl, int *count, static bool solaris_acl_get_file(const char *name, SOLARIS_ACL_T *solarisacl, int *count); static bool solaris_acl_get_fd(int fd, SOLARIS_ACL_T *solarisacl, int *count); -static bool solaris_acl_sort(SOLARIS_ACL_T acl, int count); +static bool solaris_acl_sort(SOLARIS_ACL_T theacl, int count); static SMB_ACL_PERM_T solaris_perm_to_smb_perm(const SOLARIS_PERM_T perm); static SOLARIS_PERM_T smb_perm_to_solaris_perm(const SMB_ACL_PERM_T perm); +#if 0 static bool solaris_acl_check(SOLARIS_ACL_T solaris_acl, int count); - +#endif /* public functions - the api */ @@ -347,7 +348,6 @@ static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl, { bool ret = False; int i; - int check_which, check_rc; DEBUG(10, ("entering smb_acl_to_solaris_acl\n")); @@ -717,6 +717,7 @@ static bool solaris_acl_sort(SOLARIS_ACL_T solaris_acl, int count) return True; } +#if 0 /* * acl check function: * unused at the moment but could be used to get more @@ -746,7 +747,7 @@ static bool solaris_acl_check(SOLARIS_ACL_T solaris_acl, int count) } return True; } - +#endif /* VFS operations structure */ diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c index 33bf3d0098..b90a189f7e 100644 --- a/source3/rpc_server/srv_svcctl_nt.c +++ b/source3/rpc_server/srv_svcctl_nt.c @@ -139,7 +139,7 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) SEC_ACE ace[2]; size_t i = 0; SEC_DESC *sd; - SEC_ACL *acl; + SEC_ACL *theacl; size_t sd_size; /* basic access for Everyone */ @@ -155,12 +155,12 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) /* create the security descriptor */ - if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) + if ( !(theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) return NULL; if ( !(sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, - acl, &sd_size)) ) + theacl, &sd_size)) ) return NULL; return sd; diff --git a/source3/services/services_db.c b/source3/services/services_db.c index 6d1b5d5b95..ef975cfbc4 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -91,7 +91,7 @@ static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx ) SEC_ACE ace[4]; size_t i = 0; SEC_DESC *sd = NULL; - SEC_ACL *acl = NULL; + SEC_ACL *theacl = NULL; size_t sd_size; /* basic access for Everyone */ @@ -109,12 +109,12 @@ static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx ) /* create the security descriptor */ - if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) + if ( !(theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) return NULL; if ( !(sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, - acl, &sd_size)) ) + theacl, &sd_size)) ) return NULL; return sd; diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c index 5dd788ad5f..bbbaaf089f 100644 --- a/source3/utils/profiles.c +++ b/source3/utils/profiles.c @@ -57,7 +57,7 @@ static void verbose_output(const char *format, ...) static bool swap_sid_in_acl( SEC_DESC *sd, DOM_SID *s1, DOM_SID *s2 ) { - SEC_ACL *acl; + SEC_ACL *theacl; int i; bool update = False; @@ -78,30 +78,30 @@ static bool swap_sid_in_acl( SEC_DESC *sd, DOM_SID *s1, DOM_SID *s2 ) sid_string_tos(sd->group_sid)); } - acl = sd->dacl; - verbose_output(" DACL: %d entries:\n", acl->num_aces); - for ( i=0; inum_aces; i++ ) { + theacl = sd->dacl; + verbose_output(" DACL: %d entries:\n", theacl->num_aces); + for ( i=0; inum_aces; i++ ) { verbose_output(" Trustee SID: %s\n", - sid_string_tos(&acl->aces[i].trustee)); - if ( sid_equal( &acl->aces[i].trustee, s1 ) ) { - sid_copy( &acl->aces[i].trustee, s2 ); + sid_string_tos(&theacl->aces[i].trustee)); + if ( sid_equal( &theacl->aces[i].trustee, s1 ) ) { + sid_copy( &theacl->aces[i].trustee, s2 ); update = True; verbose_output(" New Trustee SID: %s\n", - sid_string_tos(&acl->aces[i].trustee)); + sid_string_tos(&theacl->aces[i].trustee)); } } #if 0 - acl = sd->sacl; - verbose_output(" SACL: %d entries: \n", acl->num_aces); - for ( i=0; inum_aces; i++ ) { + theacl = sd->sacl; + verbose_output(" SACL: %d entries: \n", theacl->num_aces); + for ( i=0; inum_aces; i++ ) { verbose_output(" Trustee SID: %s\n", - sid_string_tos(&acl->aces[i].trustee)); - if ( sid_equal( &acl->aces[i].trustee, s1 ) ) { - sid_copy( &acl->aces[i].trustee, s2 ); + sid_string_tos(&theacl->aces[i].trustee)); + if ( sid_equal( &theacl->aces[i].trustee, s1 ) ) { + sid_copy( &theacl->aces[i].trustee, s2 ); update = True; verbose_output(" New Trustee SID: %s\n", - sid_string_tos(&acl->aces[i].trustee)); + sid_string_tos(&theacl->aces[i].trustee)); } } #endif diff --git a/source3/utils/sharesec.c b/source3/utils/sharesec.c index ae2a9adf64..4be77ecadd 100644 --- a/source3/utils/sharesec.c +++ b/source3/utils/sharesec.c @@ -298,7 +298,7 @@ static SEC_DESC* parse_acl_string(TALLOC_CTX *mem_ctx, const char *szACL, size_t { SEC_DESC *sd = NULL; SEC_ACE *ace; - SEC_ACL *acl; + SEC_ACL *theacl; int num_ace; const char *pacl; int i; @@ -326,11 +326,11 @@ static SEC_DESC* parse_acl_string(TALLOC_CTX *mem_ctx, const char *szACL, size_t pacl++; } - if ( !(acl = make_sec_acl( mem_ctx, NT4_ACL_REVISION, num_ace, ace )) ) + if ( !(theacl = make_sec_acl( mem_ctx, NT4_ACL_REVISION, num_ace, ace )) ) return NULL; sd = make_sec_desc( mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, - NULL, NULL, NULL, acl, sd_size); + NULL, NULL, NULL, theacl, sd_size); return sd; } -- cgit From 0016b9cee8d9e640e0b4604a81a900708a944c0d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Feb 2009 10:48:11 +1100 Subject: added a missing linefeed --- source4/utils/net/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c index ba5296fd97..d934403ade 100644 --- a/source4/utils/net/net.c +++ b/source4/utils/net/net.c @@ -107,7 +107,7 @@ static const struct net_functable net_functable[] = { {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage}, {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage}, {"user", "manage user accounts\n", net_user, net_user_usage}, - {"machinepw", "Get a machine password out of our SAM", net_machinepw, + {"machinepw", "Get a machine password out of our SAM\n", net_machinepw, net_machinepw_usage}, {NULL, NULL, NULL, NULL} }; -- cgit From 10c047c6f4c0f6b9fdebbdf133a3bd72aa8776de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 24 Feb 2009 00:58:29 +0100 Subject: Fix finding of setup data. --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a5b3e8322f..aca852c762 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -50,7 +50,7 @@ def find_setup_dir(): """Find the setup directory used by provision.""" dirname = os.path.dirname(__file__) if "/site-packages/" in dirname: - prefix = dirname[:dirname.index("/site-packages/")] + prefix = "/".join(dirname[:dirname.index("/site-packages/")].split("/")[:-2]) for suffix in ["share/setup", "share/samba/setup", "setup"]: ret = os.path.join(prefix, suffix) if os.path.isdir(ret): -- cgit From dcb2e7d57718ebd3db75999819ec8ef507f9dd7b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 24 Feb 2009 01:00:09 +0100 Subject: expand tabs in python file, consistent with the rest of the file. --- source4/scripting/python/samba/provision.py | 78 ++++++++++++++--------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index aca852c762..5bcb23a5d4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -93,9 +93,9 @@ class ProvisionPaths(object): self.memberofconf = None self.fedoradsinf = None self.fedoradspartitions = None - self.olmmron = None - self.olmmrserveridsconf = None - self.olmmrsyncreplconf = None + self.olmmron = None + self.olmmrserveridsconf = None + self.olmmrsyncreplconf = None class ProvisionNames(object): @@ -1178,7 +1178,7 @@ def provision_backend(setup_dir=None, message=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, ldap_backend_type=None, ldap_backend_port=None, - ol_mmr_urls=None): + ol_mmr_urls=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1300,50 +1300,50 @@ def provision_backend(setup_dir=None, message=None, { "LINK_ATTRS" : refint_attributes}) # generate serverids, ldap-urls and syncrepl-blocks for mmr hosts - mmr_on_config = "" - mmr_replicator_acl = "" - mmr_serverids_config = "" + mmr_on_config = "" + mmr_replicator_acl = "" + mmr_serverids_config = "" mmr_syncrepl_schema_config = "" - mmr_syncrepl_config_config = "" - mmr_syncrepl_user_config = "" - - if ol_mmr_urls is not None: + mmr_syncrepl_config_config = "" + mmr_syncrepl_user_config = "" + + if ol_mmr_urls is not None: # For now, make these equal mmr_pass = adminpass - url_list=filter(None,ol_mmr_urls.split(' ')) + url_list=filter(None,ol_mmr_urls.split(' ')) if (len(url_list) == 1): url_list=filter(None,ol_mmr_urls.split(',')) - mmr_on_config = "MirrorMode On" - mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" - serverid=0 - for url in url_list: - serverid=serverid+1 - mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), - { "SERVERID" : str(serverid), - "LDAPSERVER" : url }) + mmr_on_config = "MirrorMode On" + mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" + serverid=0 + for url in url_list: + serverid=serverid+1 + mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) rid=serverid*10 - rid=rid+1 - mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.schemadn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.schemadn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.configdn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.configdn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.domaindn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.domaindn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass }) @@ -1361,7 +1361,7 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, "REFINT_CONFIG": refint_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) @@ -1380,9 +1380,9 @@ def provision_backend(setup_dir=None, message=None, {"LDAPADMINPASS_B64": b64encode(adminpass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) - - if ol_mmr_urls is not None: - setup_file(setup_path("cn=replicator.ldif"), + + if ol_mmr_urls is not None: + setup_file(setup_path("cn=replicator.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), {"MMR_PASSWORD_B64": b64encode(mmr_pass), "UUID": str(uuid.uuid4()), -- cgit From 1a9bb33a7db393aff970619f20490e755f0d282b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 22:59:42 +0100 Subject: error-codes: add WERR_INVALID_USER_BUFFER. Guenther --- libcli/util/doserr.c | 1 + libcli/util/werror.h | 1 + 2 files changed, 2 insertions(+) diff --git a/libcli/util/doserr.c b/libcli/util/doserr.c index 160e7bc3e0..226c2f950d 100644 --- a/libcli/util/doserr.c +++ b/libcli/util/doserr.c @@ -135,6 +135,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS }, { "WERR_NOT_FOUND", WERR_NOT_FOUND }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, + { "WERR_INVALID_USER_BUFFER", WERR_INVALID_USER_BUFFER }, { "WERR_NO_TRUST_SAM_ACCOUNT", WERR_NO_TRUST_SAM_ACCOUNT }, { "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED }, { "WERR_NO_SHUTDOWN_IN_PROGRESS", WERR_NO_SHUTDOWN_IN_PROGRESS }, diff --git a/libcli/util/werror.h b/libcli/util/werror.h index d22516ae5c..4b34b14243 100644 --- a/libcli/util/werror.h +++ b/libcli/util/werror.h @@ -136,6 +136,7 @@ typedef uint32_t WERROR; #define WERR_TIME_SKEW W_ERROR(1398) #define WERR_EVENTLOG_FILE_CORRUPT W_ERROR(1500) #define WERR_SERVER_UNAVAILABLE W_ERROR(1722) +#define WERR_INVALID_USER_BUFFER W_ERROR(1784) #define WERR_NO_TRUST_SAM_ACCOUNT W_ERROR(1787) #define WERR_INVALID_FORM_NAME W_ERROR(1902) #define WERR_INVALID_FORM_SIZE W_ERROR(1903) -- cgit From 0449d5c285c4f2f64d1aae3654322997e65ceade Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 22:58:33 +0100 Subject: spoolss: generate size functions for printer driver structs. Guenther --- librpc/idl/spoolss.idl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 17d480261a..4809eef2e8 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -700,7 +700,7 @@ import "misc.idl", "security.idl", "winreg.idl"; spoolss_StringArray *dependent_files; [value(((ndr_size_spoolss_StringArray(previous_names, ndr->iconv_convenience, ndr->flags)-4)/2))] uint32 _ndr_size_previous_names; spoolss_StringArray *previous_names; - NTTIME driver_data; + NTTIME driver_date; hyper driver_version; [string,charset(UTF16)] uint16 *manufacturer_name; [string,charset(UTF16)] uint16 *manufacturer_url; @@ -722,7 +722,7 @@ import "misc.idl", "security.idl", "winreg.idl"; spoolss_StringArray *dependent_files; [value(((ndr_size_spoolss_StringArray(previous_names, ndr->iconv_convenience, ndr->flags)-4)/2))] uint32 _ndr_size_previous_names; spoolss_StringArray *previous_names; - NTTIME driver_data; + NTTIME driver_date; hyper driver_version; [string,charset(UTF16)] uint16 *manufacturer_name; [string,charset(UTF16)] uint16 *manufacturer_url; @@ -759,11 +759,11 @@ import "misc.idl", "security.idl", "winreg.idl"; [in,ref] spoolss_AddDriverInfoCtr *info_ctr ); - typedef struct { + typedef [public,gensize] struct { [relative] nstring *driver_name; } spoolss_DriverInfo1; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -772,7 +772,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *config_file; } spoolss_DriverInfo2; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -785,7 +785,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *default_datatype; } spoolss_DriverInfo3; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -799,7 +799,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring_array *previous_names; } spoolss_DriverInfo4; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -811,7 +811,7 @@ import "misc.idl", "security.idl", "winreg.idl"; uint32 driver_version; } spoolss_DriverInfo5; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -823,7 +823,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *monitor_name; [relative] nstring *default_datatype; [relative] nstring_array *previous_names; - NTTIME driver_data; + NTTIME driver_date; hyper driver_version; [relative] nstring *manufacturer_name; [relative] nstring *manufacturer_url; @@ -831,7 +831,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *provider; } spoolss_DriverInfo6; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -843,7 +843,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *default_datatype; [relative] nstring_array *dependent_files; [relative] nstring_array *previous_names; - NTTIME driver_data; + NTTIME driver_date; hyper driver_version; [relative] nstring *manufacturer_name; [relative] nstring *manufacturer_url; -- cgit From b9cf189404d5ef6b0a2440dc5f9670f0f6d0c131 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 24 Feb 2009 01:02:26 +0100 Subject: expand tabs in python file, consistent with the rest of the file. --- source4/scripting/python/samba/__init__.py | 2 +- source4/scripting/python/samba/samdb.py | 10 +++++----- source4/scripting/python/samba/tests/__init__.py | 4 ++-- source4/scripting/python/samba/tests/provision.py | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index e9fc26af20..a49e6e1ead 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -223,7 +223,7 @@ def check_all_substituted(text): :param text: The text to search for substitution variables """ if not "${" in text: - return + return var_start = text.find("${") var_end = text.find("}", var_start) diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 9cc55e5629..614970d3ec 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -201,11 +201,11 @@ userAccountControl: %u glue.dsdb_attach_schema_from_ldif_file(self, pf, df) def set_invocation_id(self, invocation_id): - """Set the invocation id for this SamDB handle. - - :param invocation_id: GUID of the invocation id. - """ - glue.dsdb_set_ntds_invocation_id(self, invocation_id) + """Set the invocation id for this SamDB handle. + + :param invocation_id: GUID of the invocation id. + """ + glue.dsdb_set_ntds_invocation_id(self, invocation_id) def setexpiry(self, user, expiry_seconds, noexpiry): """Set the password expiry for a user diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index d827bfa004..b342b93c49 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -70,8 +70,8 @@ class SubstituteVarTestCase(unittest.TestCase): samba.substitute_var("foo ${bla} gsff", {"bar": "bla"})) def test_check_all_substituted(self): - samba.check_all_substituted("nothing to see here") - self.assertRaises(Exception, samba.check_all_substituted, "Not subsituted: ${FOOBAR}") + samba.check_all_substituted("nothing to see here") + self.assertRaises(Exception, samba.check_all_substituted, "Not subsituted: ${FOOBAR}") class LdbExtensionTests(TestCaseInTempDir): diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 352357f694..fdac9d4ea2 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -56,7 +56,7 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir): machinepass="machinepass", dnsdomain="example.com") self.assertEquals(1, len(secrets_ldb.search("samAccountName=krbtgt,flatname=EXAMPLE,CN=Principals"))) - self.assertEquals("keytab.path", + self.assertEquals("keytab.path", secrets_ldb.searchone(basedn="flatname=EXAMPLE,CN=primary domains", expression="(privateKeytab=*)", attribute="privateKeytab")) -- cgit From b8b3a6f1fc3dd10820906118264943860a73c1c4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 00:45:25 +0100 Subject: spoolss: add spoolss_DriverInfo101 to IDL. Note that the size_is of the spoolss_DriverFileInfo is not reflected on the ndr. It is just used as pidl cannot handle a relative pointer to a static array of structs. Guenther --- librpc/idl/spoolss.idl | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 4809eef2e8..b8f4c13148 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -628,7 +628,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [string,charset(UTF16)] uint16 *driver_name; } spoolss_AddDriverInfo1; - typedef [v1_enum] enum { + typedef [v1_enum,public] enum { SPOOLSS_DRIVER_VERSION_9X = 0, SPOOLSS_DRIVER_VERSION_NT35 = 1, SPOOLSS_DRIVER_VERSION_NT4 = 2, @@ -859,6 +859,37 @@ import "misc.idl", "security.idl", "winreg.idl"; hyper min_inbox_driver_ver_version; } spoolss_DriverInfo8; + typedef [v1_enum] enum { + SPOOLSS_DRIVER_FILE_TYPE_RENDERING = 0x00000000, + SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION = 0x00000001, + SPOOLSS_DRIVER_FILE_TYPE_DATA = 0x00000002, + SPOOLSS_DRIVER_FILE_TYPE_HELP = 0x00000003, + SPOOLSS_DRIVER_FILE_TYPE_OTHER = 0x00000004 + } spoolss_DriverFileType; + + typedef [public] struct { + [relative] nstring *file_name; + spoolss_DriverFileType file_type; + uint32 file_version; + } spoolss_DriverFileInfo; + + typedef [public,gensize,nopush,nopull] struct { + spoolss_DriverOSVersion version; + [relative] nstring *driver_name; + [relative] nstring *architecture; + [relative] [size_is(file_count)] spoolss_DriverFileInfo *file_info; + uint32 file_count; + [relative] nstring *monitor_name; + [relative] nstring *default_datatype; + [relative] nstring_array *previous_names; + NTTIME driver_date; + hyper driver_version; + [relative] nstring *manufacturer_name; + [relative] nstring *manufacturer_url; + [relative] nstring *hardware_id; + [relative] nstring *provider; + } spoolss_DriverInfo101; + typedef [nodiscriminant,relative_base,public] union { [case(1)] spoolss_DriverInfo1 info1; [case(2)] spoolss_DriverInfo2 info2; @@ -867,6 +898,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [case(5)] spoolss_DriverInfo5 info5; [case(6)] spoolss_DriverInfo6 info6; [case(8)] spoolss_DriverInfo8 info8; + [case(101)] spoolss_DriverInfo101 info101; [default]; } spoolss_DriverInfo; -- cgit From 6532fea2c8469c30a187cc6d4fc36b3b32ec2dd5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 00:47:32 +0100 Subject: spoolss: add push,pull helper for spoolss_DriverInfo101. Guenther --- librpc/ndr/ndr_spoolss_buf.c | 478 +++++++++++++++++++++++++++++++++++++++++++ librpc/ndr/ndr_spoolss_buf.h | 3 + 2 files changed, 481 insertions(+) diff --git a/librpc/ndr/ndr_spoolss_buf.c b/librpc/ndr/ndr_spoolss_buf.c index d7e28ccf0e..afc06be4e0 100644 --- a/librpc/ndr/ndr_spoolss_buf.c +++ b/librpc/ndr/ndr_spoolss_buf.c @@ -544,3 +544,481 @@ _PUBLIC_ size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); } +/* hand marshall as pidl cannot (yet) generate a relative pointer to a fixed array of + * structs */ + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r) +{ + uint32_t cntr_file_info_1; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 8)); + NDR_CHECK(ndr_push_spoolss_DriverOSVersion(ndr, NDR_SCALARS, r->version)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->driver_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->architecture)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->file_info)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->file_count)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->monitor_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->default_datatype)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous_names)); + ndr->flags = _flags_save_string_array; + } + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); + NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->manufacturer_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->manufacturer_url)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->hardware_id)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->provider)); + ndr->flags = _flags_save_string; + } + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->driver_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->driver_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->driver_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->architecture) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->architecture)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->architecture)); + } + ndr->flags = _flags_save_string; + } + if (r->file_info) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->file_info)); +#if 0 + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->file_count)); +#endif + for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) { + NDR_CHECK(ndr_push_spoolss_DriverFileInfo(ndr, NDR_SCALARS, &r->file_info[cntr_file_info_1])); + } + for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) { + NDR_CHECK(ndr_push_spoolss_DriverFileInfo(ndr, NDR_BUFFERS, &r->file_info[cntr_file_info_1])); + } + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->monitor_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->monitor_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->monitor_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->default_datatype) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->default_datatype)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->default_datatype)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->previous_names) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->previous_names)); + NDR_CHECK(ndr_push_string_array(ndr, NDR_SCALARS, r->previous_names)); + } + ndr->flags = _flags_save_string_array; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->manufacturer_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->manufacturer_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->manufacturer_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->manufacturer_url) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->manufacturer_url)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->manufacturer_url)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->hardware_id) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->hardware_id)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->hardware_id)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->provider) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->provider)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->provider)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r) +{ + uint32_t _ptr_driver_name; + TALLOC_CTX *_mem_save_driver_name_0; + uint32_t _ptr_architecture; + TALLOC_CTX *_mem_save_architecture_0; + uint32_t _ptr_file_info; + uint32_t cntr_file_info_1; + TALLOC_CTX *_mem_save_file_info_0; + TALLOC_CTX *_mem_save_file_info_1; + uint32_t _ptr_monitor_name; + TALLOC_CTX *_mem_save_monitor_name_0; + uint32_t _ptr_default_datatype; + TALLOC_CTX *_mem_save_default_datatype_0; + uint32_t _ptr_previous_names; + TALLOC_CTX *_mem_save_previous_names_0; + uint32_t _ptr_manufacturer_name; + TALLOC_CTX *_mem_save_manufacturer_name_0; + uint32_t _ptr_manufacturer_url; + TALLOC_CTX *_mem_save_manufacturer_url_0; + uint32_t _ptr_hardware_id; + TALLOC_CTX *_mem_save_hardware_id_0; + uint32_t _ptr_provider; + TALLOC_CTX *_mem_save_provider_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 8)); + NDR_CHECK(ndr_pull_spoolss_DriverOSVersion(ndr, NDR_SCALARS, &r->version)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_driver_name)); + if (_ptr_driver_name) { + NDR_PULL_ALLOC(ndr, r->driver_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->driver_name, _ptr_driver_name)); + } else { + r->driver_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_architecture)); + if (_ptr_architecture) { + NDR_PULL_ALLOC(ndr, r->architecture); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->architecture, _ptr_architecture)); + } else { + r->architecture = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_file_info)); + if (_ptr_file_info) { + NDR_PULL_ALLOC(ndr, r->file_info); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->file_info, _ptr_file_info)); + } else { + r->file_info = NULL; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->file_count)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_monitor_name)); + if (_ptr_monitor_name) { + NDR_PULL_ALLOC(ndr, r->monitor_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->monitor_name, _ptr_monitor_name)); + } else { + r->monitor_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_default_datatype)); + if (_ptr_default_datatype) { + NDR_PULL_ALLOC(ndr, r->default_datatype); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->default_datatype, _ptr_default_datatype)); + } else { + r->default_datatype = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_previous_names)); + if (_ptr_previous_names) { + NDR_PULL_ALLOC(ndr, r->previous_names); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->previous_names, _ptr_previous_names)); + } else { + r->previous_names = NULL; + } + ndr->flags = _flags_save_string_array; + } + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); + NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_manufacturer_name)); + if (_ptr_manufacturer_name) { + NDR_PULL_ALLOC(ndr, r->manufacturer_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->manufacturer_name, _ptr_manufacturer_name)); + } else { + r->manufacturer_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_manufacturer_url)); + if (_ptr_manufacturer_url) { + NDR_PULL_ALLOC(ndr, r->manufacturer_url); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->manufacturer_url, _ptr_manufacturer_url)); + } else { + r->manufacturer_url = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_hardware_id)); + if (_ptr_hardware_id) { + NDR_PULL_ALLOC(ndr, r->hardware_id); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->hardware_id, _ptr_hardware_id)); + } else { + r->hardware_id = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_provider)); + if (_ptr_provider) { + NDR_PULL_ALLOC(ndr, r->provider); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->provider, _ptr_provider)); + } else { + r->provider = NULL; + } + ndr->flags = _flags_save_string; + } + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->driver_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->driver_name)); + _mem_save_driver_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->driver_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->driver_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_driver_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->architecture) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->architecture)); + _mem_save_architecture_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->architecture, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->architecture)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_architecture_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + if (r->file_info) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->file_info)); + _mem_save_file_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->file_info, 0); +#if 0 + NDR_CHECK(ndr_pull_array_size(ndr, &r->file_info)); +#else + NDR_CHECK(ndr_token_store(ndr, &ndr->array_size_list, &r->file_info, r->file_count)); +#endif + NDR_PULL_ALLOC_N(ndr, r->file_info, ndr_get_array_size(ndr, &r->file_info)); + _mem_save_file_info_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->file_info, 0); + for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) { + NDR_CHECK(ndr_pull_spoolss_DriverFileInfo(ndr, NDR_SCALARS, &r->file_info[cntr_file_info_1])); + } + for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) { + NDR_CHECK(ndr_pull_spoolss_DriverFileInfo(ndr, NDR_BUFFERS, &r->file_info[cntr_file_info_1])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_file_info_1, 0); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_file_info_0, 0); + ndr->offset = _relative_save_offset; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->monitor_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->monitor_name)); + _mem_save_monitor_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->monitor_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->monitor_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_monitor_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->default_datatype) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->default_datatype)); + _mem_save_default_datatype_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->default_datatype, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->default_datatype)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_default_datatype_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->previous_names) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->previous_names)); + _mem_save_previous_names_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->previous_names, 0); + NDR_CHECK(ndr_pull_string_array(ndr, NDR_SCALARS, &r->previous_names)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_previous_names_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string_array; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->manufacturer_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->manufacturer_name)); + _mem_save_manufacturer_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->manufacturer_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->manufacturer_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_manufacturer_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->manufacturer_url) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->manufacturer_url)); + _mem_save_manufacturer_url_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->manufacturer_url, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->manufacturer_url)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_manufacturer_url_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->hardware_id) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->hardware_id)); + _mem_save_hardware_id_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->hardware_id, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->hardware_id)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_hardware_id_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->provider) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->provider)); + _mem_save_provider_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->provider, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->provider)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_provider_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + if (r->file_info) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->file_info, r->file_count)); + } + } + return NDR_ERR_SUCCESS; +} diff --git a/librpc/ndr/ndr_spoolss_buf.h b/librpc/ndr/ndr_spoolss_buf.h index 801737610f..5ed848d7e0 100644 --- a/librpc/ndr/ndr_spoolss_buf.h +++ b/librpc/ndr/ndr_spoolss_buf.h @@ -39,6 +39,9 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag enum ndr_err_code ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r); uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, struct smb_iconv_convenience *ic, uint32_t flags); size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r, struct smb_iconv_convenience *ic, int flags); +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r); +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r); + #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) -- cgit From 3e796103b28f1279bdaa481b7d5c4447d62683bb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 01:03:19 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 312 +++++++++++++++++++++++++++++++++++++++---- librpc/gen_ndr/ndr_spoolss.h | 31 +++++ librpc/gen_ndr/spoolss.h | 65 +++++++-- 3 files changed, 369 insertions(+), 39 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 242041fb8d..3e210b2417 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -4796,13 +4796,13 @@ _PUBLIC_ void ndr_print_spoolss_AddDriverInfo1(struct ndr_print *ndr, const char ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r) +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r) { uint32_t v; NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); @@ -5704,7 +5704,7 @@ static enum ndr_err_code ndr_push_spoolss_AddDriverInfo6(struct ndr_push *ndr, i NDR_CHECK(ndr_push_unique_ptr(ndr, r->dependent_files)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ((ndr_size_spoolss_StringArray(r->previous_names, ndr->iconv_convenience, ndr->flags) - 4) / 2))); NDR_CHECK(ndr_push_unique_ptr(ndr, r->previous_names)); - NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_data)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->manufacturer_name)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->manufacturer_url)); @@ -5889,7 +5889,7 @@ static enum ndr_err_code ndr_pull_spoolss_AddDriverInfo6(struct ndr_pull *ndr, i } else { r->previous_names = NULL; } - NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_data)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_manufacturer_name)); if (_ptr_manufacturer_name) { @@ -6144,7 +6144,7 @@ _PUBLIC_ void ndr_print_spoolss_AddDriverInfo6(struct ndr_print *ndr, const char ndr_print_spoolss_StringArray(ndr, "previous_names", r->previous_names); } ndr->depth--; - ndr_print_NTTIME(ndr, "driver_data", r->driver_data); + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); ndr_print_hyper(ndr, "driver_version", r->driver_version); ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); ndr->depth++; @@ -6190,7 +6190,7 @@ static enum ndr_err_code ndr_push_spoolss_AddDriverInfo8(struct ndr_push *ndr, i NDR_CHECK(ndr_push_unique_ptr(ndr, r->dependent_files)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ((ndr_size_spoolss_StringArray(r->previous_names, ndr->iconv_convenience, ndr->flags) - 4) / 2))); NDR_CHECK(ndr_push_unique_ptr(ndr, r->previous_names)); - NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_data)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->manufacturer_name)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->manufacturer_url)); @@ -6419,7 +6419,7 @@ static enum ndr_err_code ndr_pull_spoolss_AddDriverInfo8(struct ndr_pull *ndr, i } else { r->previous_names = NULL; } - NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_data)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_manufacturer_name)); if (_ptr_manufacturer_name) { @@ -6757,7 +6757,7 @@ _PUBLIC_ void ndr_print_spoolss_AddDriverInfo8(struct ndr_print *ndr, const char ndr_print_spoolss_StringArray(ndr, "previous_names", r->previous_names); } ndr->depth--; - ndr_print_NTTIME(ndr, "driver_data", r->driver_data); + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); ndr_print_hyper(ndr, "driver_version", r->driver_version); ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); ndr->depth++; @@ -7148,7 +7148,7 @@ _PUBLIC_ void ndr_print_spoolss_AddDriverInfoCtr(struct ndr_print *ndr, const ch ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo1 *r) +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo1 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -7173,7 +7173,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo1(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo1 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo1 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -7225,7 +7225,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo1(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo2 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo1(const struct spoolss_DriverInfo1 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo1, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo2 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -7311,7 +7316,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo2(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo2 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo2 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -7505,7 +7510,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo2(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo3 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo2(const struct spoolss_DriverInfo2 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo2, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo3 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -7651,7 +7661,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo3(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo3 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo3 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -7985,7 +7995,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo3(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo4 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo3(const struct spoolss_DriverInfo3 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo3, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo4 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -8146,7 +8161,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo4(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo4 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo4 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -8515,7 +8530,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo4(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo5 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo4(const struct spoolss_DriverInfo4 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo4, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo5 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -8604,7 +8624,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo5(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo5 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo5 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -8804,7 +8824,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo5(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo6 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo5(const struct spoolss_DriverInfo5 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo5, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo6 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 8)); @@ -8869,7 +8894,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous_names)); ndr->flags = _flags_save_string_array; } - NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_data)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); { uint32_t _flags_save_string = ndr->flags; @@ -9027,7 +9052,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo6 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo6 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -9180,7 +9205,7 @@ static enum ndr_err_code ndr_pull_spoolss_DriverInfo6(struct ndr_pull *ndr, int } ndr->flags = _flags_save_string_array; } - NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_data)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); { uint32_t _flags_save_string = ndr->flags; @@ -9511,7 +9536,7 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo6(struct ndr_print *ndr, const char *n ndr_print_string_array(ndr, "previous_names", r->previous_names); } ndr->depth--; - ndr_print_NTTIME(ndr, "driver_data", r->driver_data); + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); ndr_print_hyper(ndr, "driver_version", r->driver_version); ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); ndr->depth++; @@ -9540,7 +9565,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo6(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo8 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo6(const struct spoolss_DriverInfo6 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo6, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo8 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 8)); @@ -9605,7 +9635,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous_names)); ndr->flags = _flags_save_string_array; } - NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_data)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); { uint32_t _flags_save_string = ndr->flags; @@ -9841,7 +9871,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo8(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo8 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo8(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo8 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -10004,7 +10034,7 @@ static enum ndr_err_code ndr_pull_spoolss_DriverInfo8(struct ndr_pull *ndr, int } ndr->flags = _flags_save_string_array; } - NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_data)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); { uint32_t _flags_save_string = ndr->flags; @@ -10473,7 +10503,7 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo8(struct ndr_print *ndr, const char *n ndr_print_string_array(ndr, "previous_names", r->previous_names); } ndr->depth--; - ndr_print_NTTIME(ndr, "driver_data", r->driver_data); + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); ndr_print_hyper(ndr, "driver_version", r->driver_version); ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); ndr->depth++; @@ -10535,6 +10565,208 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo8(struct ndr_print *ndr, const char *n ndr->depth--; } +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo8(const struct spoolss_DriverInfo8 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo8, ic); +} + +static enum ndr_err_code ndr_push_spoolss_DriverFileType(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverFileType r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_DriverFileType(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverFileType *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_DriverFileType(struct ndr_print *ndr, const char *name, enum spoolss_DriverFileType r) +{ + const char *val = NULL; + + switch (r) { + case SPOOLSS_DRIVER_FILE_TYPE_RENDERING: val = "SPOOLSS_DRIVER_FILE_TYPE_RENDERING"; break; + case SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION: val = "SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION"; break; + case SPOOLSS_DRIVER_FILE_TYPE_DATA: val = "SPOOLSS_DRIVER_FILE_TYPE_DATA"; break; + case SPOOLSS_DRIVER_FILE_TYPE_HELP: val = "SPOOLSS_DRIVER_FILE_TYPE_HELP"; break; + case SPOOLSS_DRIVER_FILE_TYPE_OTHER: val = "SPOOLSS_DRIVER_FILE_TYPE_OTHER"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverFileInfo(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverFileInfo *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->file_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_spoolss_DriverFileType(ndr, NDR_SCALARS, r->file_type)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->file_version)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->file_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->file_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->file_name)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverFileInfo(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverFileInfo *r) +{ + uint32_t _ptr_file_name; + TALLOC_CTX *_mem_save_file_name_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_file_name)); + if (_ptr_file_name) { + NDR_PULL_ALLOC(ndr, r->file_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->file_name, _ptr_file_name)); + } else { + r->file_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_spoolss_DriverFileType(ndr, NDR_SCALARS, &r->file_type)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->file_version)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->file_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->file_name)); + _mem_save_file_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->file_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->file_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_file_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_DriverFileInfo(struct ndr_print *ndr, const char *name, const struct spoolss_DriverFileInfo *r) +{ + ndr_print_struct(ndr, name, "spoolss_DriverFileInfo"); + ndr->depth++; + ndr_print_ptr(ndr, "file_name", r->file_name); + ndr->depth++; + if (r->file_name) { + ndr_print_string(ndr, "file_name", r->file_name); + } + ndr->depth--; + ndr_print_spoolss_DriverFileType(ndr, "file_type", r->file_type); + ndr_print_uint32(ndr, "file_version", r->file_version); + ndr->depth--; +} + +_PUBLIC_ void ndr_print_spoolss_DriverInfo101(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo101 *r) +{ + uint32_t cntr_file_info_1; + ndr_print_struct(ndr, name, "spoolss_DriverInfo101"); + ndr->depth++; + ndr_print_spoolss_DriverOSVersion(ndr, "version", r->version); + ndr_print_ptr(ndr, "driver_name", r->driver_name); + ndr->depth++; + if (r->driver_name) { + ndr_print_string(ndr, "driver_name", r->driver_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "architecture", r->architecture); + ndr->depth++; + if (r->architecture) { + ndr_print_string(ndr, "architecture", r->architecture); + } + ndr->depth--; + ndr_print_ptr(ndr, "file_info", r->file_info); + ndr->depth++; + if (r->file_info) { + ndr->print(ndr, "%s: ARRAY(%d)", "file_info", (int)r->file_count); + ndr->depth++; + for (cntr_file_info_1=0;cntr_file_info_1file_count;cntr_file_info_1++) { + char *idx_1=NULL; + if (asprintf(&idx_1, "[%d]", cntr_file_info_1) != -1) { + ndr_print_spoolss_DriverFileInfo(ndr, "file_info", &r->file_info[cntr_file_info_1]); + free(idx_1); + } + } + ndr->depth--; + } + ndr->depth--; + ndr_print_uint32(ndr, "file_count", r->file_count); + ndr_print_ptr(ndr, "monitor_name", r->monitor_name); + ndr->depth++; + if (r->monitor_name) { + ndr_print_string(ndr, "monitor_name", r->monitor_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "default_datatype", r->default_datatype); + ndr->depth++; + if (r->default_datatype) { + ndr_print_string(ndr, "default_datatype", r->default_datatype); + } + ndr->depth--; + ndr_print_ptr(ndr, "previous_names", r->previous_names); + ndr->depth++; + if (r->previous_names) { + ndr_print_string_array(ndr, "previous_names", r->previous_names); + } + ndr->depth--; + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); + ndr_print_hyper(ndr, "driver_version", r->driver_version); + ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); + ndr->depth++; + if (r->manufacturer_name) { + ndr_print_string(ndr, "manufacturer_name", r->manufacturer_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "manufacturer_url", r->manufacturer_url); + ndr->depth++; + if (r->manufacturer_url) { + ndr_print_string(ndr, "manufacturer_url", r->manufacturer_url); + } + ndr->depth--; + ndr_print_ptr(ndr, "hardware_id", r->hardware_id); + ndr->depth++; + if (r->hardware_id) { + ndr_print_string(ndr, "hardware_id", r->hardware_id); + } + ndr->depth--; + ndr_print_ptr(ndr, "provider", r->provider); + ndr->depth++; + if (r->provider) { + ndr_print_string(ndr, "provider", r->provider); + } + ndr->depth--; + ndr->depth--; +} + +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo101(const struct spoolss_DriverInfo101 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo101, ic); +} + _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_DriverInfo *r) { uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr); @@ -10583,6 +10815,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int NDR_CHECK(ndr_push_spoolss_DriverInfo8(ndr, NDR_SCALARS, &r->info8)); break; } + case 101: { + NDR_CHECK(ndr_push_align(ndr, 8)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_DriverInfo101(ndr, NDR_SCALARS, &r->info101)); + break; } + default: { break; } @@ -10620,6 +10858,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int NDR_CHECK(ndr_push_spoolss_DriverInfo8(ndr, NDR_BUFFERS, &r->info8)); break; + case 101: + NDR_CHECK(ndr_push_spoolss_DriverInfo101(ndr, NDR_BUFFERS, &r->info101)); + break; + default: break; @@ -10678,6 +10920,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo(struct ndr_pull *ndr, int NDR_CHECK(ndr_pull_spoolss_DriverInfo8(ndr, NDR_SCALARS, &r->info8)); break; } + case 101: { + NDR_CHECK(ndr_pull_align(ndr, 8)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_DriverInfo101(ndr, NDR_SCALARS, &r->info101)); + break; } + default: { break; } @@ -10714,6 +10962,10 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo(struct ndr_pull *ndr, int NDR_CHECK(ndr_pull_spoolss_DriverInfo8(ndr, NDR_BUFFERS, &r->info8)); break; + case 101: + NDR_CHECK(ndr_pull_spoolss_DriverInfo101(ndr, NDR_BUFFERS, &r->info101)); + break; + default: break; @@ -10757,6 +11009,10 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo(struct ndr_print *ndr, const char *na ndr_print_spoolss_DriverInfo8(ndr, "info8", &r->info8); break; + case 101: + ndr_print_spoolss_DriverInfo101(ndr, "info101", &r->info101); + break; + default: break; diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index b9a533ab38..5b32d510c0 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -256,6 +256,8 @@ enum ndr_err_code ndr_push_spoolss_StringArray(struct ndr_push *ndr, int ndr_fla enum ndr_err_code ndr_pull_spoolss_StringArray(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray *r); void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray *r); void ndr_print_spoolss_AddDriverInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo1 *r); +enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r); +enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r); void ndr_print_spoolss_DriverOSVersion(struct ndr_print *ndr, const char *name, enum spoolss_DriverOSVersion r); void ndr_print_spoolss_AddDriverInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo2 *r); void ndr_print_spoolss_AddDriverInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo3 *r); @@ -264,13 +266,42 @@ void ndr_print_spoolss_AddDriverInfo6(struct ndr_print *ndr, const char *name, c void ndr_print_spoolss_AddDriverInfo8(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo8 *r); void ndr_print_spoolss_AddDriverInfo(struct ndr_print *ndr, const char *name, const union spoolss_AddDriverInfo *r); void ndr_print_spoolss_AddDriverInfoCtr(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfoCtr *r); +enum ndr_err_code ndr_push_spoolss_DriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo1 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo1 *r); void ndr_print_spoolss_DriverInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo1 *r); +size_t ndr_size_spoolss_DriverInfo1(const struct spoolss_DriverInfo1 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo2 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo2 *r); void ndr_print_spoolss_DriverInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo2 *r); +size_t ndr_size_spoolss_DriverInfo2(const struct spoolss_DriverInfo2 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo3 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo3 *r); void ndr_print_spoolss_DriverInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo3 *r); +size_t ndr_size_spoolss_DriverInfo3(const struct spoolss_DriverInfo3 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo4 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo4 *r); void ndr_print_spoolss_DriverInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo4 *r); +size_t ndr_size_spoolss_DriverInfo4(const struct spoolss_DriverInfo4 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo5 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo5 *r); void ndr_print_spoolss_DriverInfo5(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo5 *r); +size_t ndr_size_spoolss_DriverInfo5(const struct spoolss_DriverInfo5 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo6 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo6 *r); void ndr_print_spoolss_DriverInfo6(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo6 *r); +size_t ndr_size_spoolss_DriverInfo6(const struct spoolss_DriverInfo6 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo8 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo8(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo8 *r); void ndr_print_spoolss_DriverInfo8(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo8 *r); +size_t ndr_size_spoolss_DriverInfo8(const struct spoolss_DriverInfo8 *r, struct smb_iconv_convenience *ic, int flags); +void ndr_print_spoolss_DriverFileType(struct ndr_print *ndr, const char *name, enum spoolss_DriverFileType r); +enum ndr_err_code ndr_push_spoolss_DriverFileInfo(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverFileInfo *r); +enum ndr_err_code ndr_pull_spoolss_DriverFileInfo(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverFileInfo *r); +void ndr_print_spoolss_DriverFileInfo(struct ndr_print *ndr, const char *name, const struct spoolss_DriverFileInfo *r); +enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r); +void ndr_print_spoolss_DriverInfo101(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo101 *r); +size_t ndr_size_spoolss_DriverInfo101(const struct spoolss_DriverInfo101 *r, struct smb_iconv_convenience *ic, int flags); enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_DriverInfo *r); enum ndr_err_code ndr_pull_spoolss_DriverInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_DriverInfo *r); void ndr_print_spoolss_DriverInfo(struct ndr_print *ndr, const char *name, const union spoolss_DriverInfo *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 150bf04d6f..0e8ba37cb7 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -635,7 +635,7 @@ struct spoolss_AddDriverInfo6 { struct spoolss_StringArray *dependent_files;/* [unique] */ uint32_t _ndr_size_previous_names;/* [value(((ndr_size_spoolss_StringArray(previous_names,ndr->iconv_convenience,ndr->flags)-4)/2))] */ struct spoolss_StringArray *previous_names;/* [unique] */ - NTTIME driver_data; + NTTIME driver_date; uint64_t driver_version; const char *manufacturer_name;/* [unique,charset(UTF16)] */ const char *manufacturer_url;/* [unique,charset(UTF16)] */ @@ -657,7 +657,7 @@ struct spoolss_AddDriverInfo8 { struct spoolss_StringArray *dependent_files;/* [unique] */ uint32_t _ndr_size_previous_names;/* [value(((ndr_size_spoolss_StringArray(previous_names,ndr->iconv_convenience,ndr->flags)-4)/2))] */ struct spoolss_StringArray *previous_names;/* [unique] */ - NTTIME driver_data; + NTTIME driver_date; uint64_t driver_version; const char *manufacturer_name;/* [unique,charset(UTF16)] */ const char *manufacturer_url;/* [unique,charset(UTF16)] */ @@ -691,7 +691,7 @@ struct spoolss_AddDriverInfoCtr { struct spoolss_DriverInfo1 { const char * driver_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo2 { enum spoolss_DriverOSVersion version; @@ -700,7 +700,7 @@ struct spoolss_DriverInfo2 { const char * driver_path;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * data_file;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * config_file;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo3 { enum spoolss_DriverOSVersion version; @@ -713,7 +713,7 @@ struct spoolss_DriverInfo3 { const char ** dependent_files;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo4 { enum spoolss_DriverOSVersion version; @@ -727,7 +727,7 @@ struct spoolss_DriverInfo4 { const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char ** previous_names;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo5 { enum spoolss_DriverOSVersion version; @@ -739,7 +739,7 @@ struct spoolss_DriverInfo5 { uint32_t driver_attributes; uint32_t config_version; uint32_t driver_version; -}; +}/* [gensize,public] */; struct spoolss_DriverInfo6 { enum spoolss_DriverOSVersion version; @@ -753,13 +753,13 @@ struct spoolss_DriverInfo6 { const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char ** previous_names;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ - NTTIME driver_data; + NTTIME driver_date; uint64_t driver_version; const char * manufacturer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * manufacturer_url;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * hardware_id;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * provider;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo8 { enum spoolss_DriverOSVersion version; @@ -773,7 +773,7 @@ struct spoolss_DriverInfo8 { const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char ** dependent_files;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char ** previous_names;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ - NTTIME driver_data; + NTTIME driver_date; uint64_t driver_version; const char * manufacturer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * manufacturer_url;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ @@ -787,7 +787,49 @@ struct spoolss_DriverInfo8 { const char ** core_driver_dependencies;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ NTTIME min_inbox_driver_ver_date; uint64_t min_inbox_driver_ver_version; -}; +}/* [gensize,public] */; + +enum spoolss_DriverFileType +#ifndef USE_UINT_ENUMS + { + SPOOLSS_DRIVER_FILE_TYPE_RENDERING=0x00000000, + SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION=0x00000001, + SPOOLSS_DRIVER_FILE_TYPE_DATA=0x00000002, + SPOOLSS_DRIVER_FILE_TYPE_HELP=0x00000003, + SPOOLSS_DRIVER_FILE_TYPE_OTHER=0x00000004 +} +#else + { __donnot_use_enum_spoolss_DriverFileType=0x7FFFFFFF} +#define SPOOLSS_DRIVER_FILE_TYPE_RENDERING ( 0x00000000 ) +#define SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION ( 0x00000001 ) +#define SPOOLSS_DRIVER_FILE_TYPE_DATA ( 0x00000002 ) +#define SPOOLSS_DRIVER_FILE_TYPE_HELP ( 0x00000003 ) +#define SPOOLSS_DRIVER_FILE_TYPE_OTHER ( 0x00000004 ) +#endif +; + +struct spoolss_DriverFileInfo { + const char * file_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + enum spoolss_DriverFileType file_type; + uint32_t file_version; +}/* [public] */; + +struct spoolss_DriverInfo101 { + enum spoolss_DriverOSVersion version; + const char * driver_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * architecture;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + struct spoolss_DriverFileInfo *file_info;/* [relative,size_is(file_count)] */ + uint32_t file_count; + const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char ** previous_names;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + NTTIME driver_date; + uint64_t driver_version; + const char * manufacturer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * manufacturer_url;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * hardware_id;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * provider;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ +}/* [gensize,nopush,public,nopull] */; union spoolss_DriverInfo { struct spoolss_DriverInfo1 info1;/* [case] */ @@ -797,6 +839,7 @@ union spoolss_DriverInfo { struct spoolss_DriverInfo5 info5;/* [case(5)] */ struct spoolss_DriverInfo6 info6;/* [case(6)] */ struct spoolss_DriverInfo8 info8;/* [case(8)] */ + struct spoolss_DriverInfo101 info101;/* [case(101)] */ }/* [relative_base,nodiscriminant,public] */; struct spoolss_DriverDirectoryInfo1 { -- cgit From bcd6e5ec3315b14cedf7437a70c34d233ded082e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 11:43:32 +0100 Subject: s3-spoolss: fix notify_printer_status_byname. This took me almost a week to find, so here a little longer explanation: When a windows client registers printer *status* change notifies using spoolss_RemoteFindFirstChangeNotify, it registers them to a print server handle, not a printer handle. We were then correctly monitoring the printer status changes but were sending out the spoolss_RouterReplyPrinterEx via the back-channel connection with job_id set to 0 (which we only may do for monitored printer change status notifies on printer handlers, not print server handles). Windows was then showing a new empty dummy printer icon in the explorer as it cannot route the notify event to the approriate local handle. It also discarded the content of the notify event message of course. With this, printer change notify for pausing, resuming and purging printers nicely works again here. Jerry, Tim and all other printing gurus, please check. Guenther --- source3/printing/notify.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/printing/notify.c b/source3/printing/notify.c index d478b86f91..e19212eea8 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -397,8 +397,10 @@ void notify_printer_status_byname(const char *sharename, uint32 status) { /* Printer status stored in value1 */ + int snum = print_queue_snum(sharename); + send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE, - PRINTER_NOTIFY_STATUS, 0, + PRINTER_NOTIFY_STATUS, snum, status, 0, 0); } -- cgit From faa1100d229aef56da5d48f5c19ec901e520f8ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Feb 2009 16:22:43 -0800 Subject: More warning fixes for Solaris. Jeremy. --- lib/replace/getifaddrs.c | 9 ------- source3/client/client.c | 6 ++--- source3/lib/ldap_debug_handler.c | 4 +-- source3/lib/smbldap.c | 2 ++ source3/lib/system.c | 3 +-- source3/lib/tdb_validate.c | 5 ++-- source3/libsmb/libsmb_dir.c | 2 +- source3/modules/vfs_extd_audit.c | 8 +++--- source3/nmbd/nmbd.c | 14 +++++------ source3/smbd/open.c | 2 +- source3/smbd/posix_acls.c | 52 +++++++++++++++++++-------------------- source3/smbd/server.c | 2 +- source3/smbd/sesssetup.c | 4 +-- source3/utils/smbget.c | 6 +++-- source3/winbindd/winbindd.c | 2 +- source3/winbindd/winbindd_cache.c | 18 +++++++------- source3/winbindd/winbindd_dual.c | 2 +- 17 files changed, 67 insertions(+), 74 deletions(-) diff --git a/lib/replace/getifaddrs.c b/lib/replace/getifaddrs.c index f6f0ec080c..3a91bb40d2 100644 --- a/lib/replace/getifaddrs.c +++ b/lib/replace/getifaddrs.c @@ -84,9 +84,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; @@ -164,9 +161,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; @@ -265,9 +259,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) int fd, i; struct ifconf ifc; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; diff --git a/source3/client/client.c b/source3/client/client.c index 2f9e3c0d49..aaa9e35d96 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1784,13 +1784,13 @@ static struct file_list { Free a file_list structure. ****************************************************************************/ -static void free_file_list (struct file_list *list_head) +static void free_file_list (struct file_list *l_head) { struct file_list *list, *next; - for (list = list_head; list; list = next) { + for (list = l_head; list; list = next) { next = list->next; - DLIST_REMOVE(list_head, list); + DLIST_REMOVE(l_head, list); SAFE_FREE(list->file_path); SAFE_FREE(list); } diff --git a/source3/lib/ldap_debug_handler.c b/source3/lib/ldap_debug_handler.c index 2181ff014d..98623d1985 100644 --- a/source3/lib/ldap_debug_handler.c +++ b/source3/lib/ldap_debug_handler.c @@ -19,13 +19,11 @@ #include "includes.h" -#if HAVE_LDAP - +#if defined(HAVE_LDAP) && defined(HAVE_LBER_LOG_PRINT_FN) static void samba_ldap_log_print_fn(LDAP_CONST char *data) { DEBUG(lp_ldap_debug_threshold(), ("[LDAP] %s", data)); } - #endif void init_ldap_debugging(void) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index f0561a5081..e24d35818c 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -581,7 +581,9 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) int smb_ldap_start_tls(LDAP *ldap_struct, int version) { +#ifdef LDAP_OPT_X_TLS int rc; +#endif if (lp_ldap_ssl() != LDAP_SSL_START_TLS) { return LDAP_SUCCESS; diff --git a/source3/lib/system.c b/source3/lib/system.c index ed66666ddb..8bdc9fa92b 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -2008,7 +2008,6 @@ static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size) static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size) { ssize_t len = 0; - int stop = 0; DIR *dirp; struct dirent *de; int newfd = dup(attrdirfd); @@ -2080,7 +2079,7 @@ static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode) { int filedes = openat(fildes, path, oflag, mode); if (filedes == -1) { - DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno))); + DEBUG(10,("openat FAILED: fd: %d, path: %s, errno: %s\n",filedes,path,strerror(errno))); if (errno == EINVAL) { errno = ENOTSUP; } else { diff --git a/source3/lib/tdb_validate.c b/source3/lib/tdb_validate.c index 1f5dfe4d25..092546e3eb 100644 --- a/source3/lib/tdb_validate.c +++ b/source3/lib/tdb_validate.c @@ -118,7 +118,8 @@ int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn) /* parent */ - DEBUG(10, ("tdb_validate: fork succeeded, child PID = %d\n",child_pid)); + DEBUG(10, ("tdb_validate: fork succeeded, child PID = %u\n", + (unsigned int)child_pid)); DEBUG(10, ("tdb_validate: waiting for child to finish...\n")); while ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) { @@ -134,7 +135,7 @@ int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn) } if (wait_pid != child_pid) { DEBUG(1, ("tdb_validate: waitpid returned pid %d, " - "but %d was expected\n", wait_pid, child_pid)); + "but %u was expected\n", wait_pid, (unsigned int)child_pid)); goto done; } diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 1843fe262f..56661af70b 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -1519,7 +1519,7 @@ SMBC_chmod_ctx(SMBCCTX *context, return -1; } - DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); + DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, (unsigned int)newmode)); if (SMBC_parse_path(frame, context, diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c index d7c9d39c5e..b59a780f52 100644 --- a/source3/modules/vfs_extd_audit.c +++ b/source3/modules/vfs_extd_audit.c @@ -310,7 +310,7 @@ static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: chmod %s mode 0x%x %s %s\n", - path, mode, + path, (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); @@ -330,7 +330,7 @@ static int audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t m (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: chmod_acl %s mode 0x%x %s %s\n", - path, mode, + path, (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); @@ -350,7 +350,7 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s", - fsp->fsp_name, mode, + fsp->fsp_name, (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); @@ -370,7 +370,7 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s", - fsp->fsp_name, mode, + fsp->fsp_name, (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index adefb7d94f..3279466602 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -412,18 +412,18 @@ static void msg_nmbd_send_packet(struct messaging_context *msg, const struct sockaddr_storage *pss; const struct in_addr *local_ip; - DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src))); + DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src))); if (data->length != sizeof(struct packet_struct)) { - DEBUG(2, ("Discarding invalid packet length from %d\n", - procid_to_pid(&src))); + DEBUG(2, ("Discarding invalid packet length from %u\n", + (unsigned int)procid_to_pid(&src))); return; } if ((p->packet_type != NMB_PACKET) && (p->packet_type != DGRAM_PACKET)) { - DEBUG(2, ("Discarding invalid packet type from %d: %d\n", - procid_to_pid(&src), p->packet_type)); + DEBUG(2, ("Discarding invalid packet type from %u: %d\n", + (unsigned int)procid_to_pid(&src), p->packet_type)); return; } @@ -431,8 +431,8 @@ static void msg_nmbd_send_packet(struct messaging_context *msg, pss = iface_ip((struct sockaddr *)&ss); if (pss == NULL) { - DEBUG(2, ("Could not find ip for packet from %d\n", - procid_to_pid(&src))); + DEBUG(2, ("Could not find ip for packet from %u\n", + (unsigned int)procid_to_pid(&src))); return; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index ac7c35c240..a42705adb6 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1440,7 +1440,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, "create_disposition = 0x%x create_options=0x%x " "unix mode=0%o oplock_request=%d\n", fname, new_dos_attributes, access_mask, share_access, - create_disposition, create_options, unx_mode, + create_disposition, create_options, (unsigned int)unx_mode, oplock_request)); if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) { diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index e9b581efe8..2f84a831c6 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -719,12 +719,12 @@ static struct pai_val *load_inherited_info(const struct connection_struct *conn, Count a linked list of canonical ACE entries. ****************************************************************************/ -static size_t count_canon_ace_list( canon_ace *list_head ) +static size_t count_canon_ace_list( canon_ace *l_head ) { size_t count = 0; canon_ace *ace; - for (ace = list_head; ace; ace = ace->next) + for (ace = l_head; ace; ace = ace->next) count++; return count; @@ -734,13 +734,13 @@ static size_t count_canon_ace_list( canon_ace *list_head ) Free a linked list of canonical ACE entries. ****************************************************************************/ -static void free_canon_ace_list( canon_ace *list_head ) +static void free_canon_ace_list( canon_ace *l_head ) { canon_ace *list, *next; - for (list = list_head; list; list = next) { + for (list = l_head; list; list = next) { next = list->next; - DLIST_REMOVE(list_head, list); + DLIST_REMOVE(l_head, list); SAFE_FREE(list); } } @@ -916,7 +916,7 @@ static bool identity_in_ace_equal(canon_ace *ace1, canon_ace *ace2) static void merge_aces( canon_ace **pp_list_head ) { - canon_ace *list_head = *pp_list_head; + canon_ace *l_head = *pp_list_head; canon_ace *curr_ace_outer; canon_ace *curr_ace_outer_next; @@ -925,7 +925,7 @@ static void merge_aces( canon_ace **pp_list_head ) * with identical SIDs. */ - for (curr_ace_outer = list_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) { + for (curr_ace_outer = l_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) { canon_ace *curr_ace; canon_ace *curr_ace_next; @@ -947,7 +947,7 @@ static void merge_aces( canon_ace **pp_list_head ) /* Merge two allow or two deny ACE's. */ curr_ace_outer->perms |= curr_ace->perms; - DLIST_REMOVE(list_head, curr_ace); + DLIST_REMOVE(l_head, curr_ace); SAFE_FREE(curr_ace); curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */ } @@ -960,7 +960,7 @@ static void merge_aces( canon_ace **pp_list_head ) * appears only once in the list. */ - for (curr_ace_outer = list_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) { + for (curr_ace_outer = l_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) { canon_ace *curr_ace; canon_ace *curr_ace_next; @@ -992,7 +992,7 @@ static void merge_aces( canon_ace **pp_list_head ) * The deny overrides the allow. Remove the allow. */ - DLIST_REMOVE(list_head, curr_ace); + DLIST_REMOVE(l_head, curr_ace); SAFE_FREE(curr_ace); curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */ @@ -1008,7 +1008,7 @@ static void merge_aces( canon_ace **pp_list_head ) * before we can get to an allow ace. */ - DLIST_REMOVE(list_head, curr_ace_outer); + DLIST_REMOVE(l_head, curr_ace_outer); SAFE_FREE(curr_ace_outer); break; } @@ -1019,7 +1019,7 @@ static void merge_aces( canon_ace **pp_list_head ) /* We may have modified the list. */ - *pp_list_head = list_head; + *pp_list_head = l_head; } /**************************************************************************** @@ -2305,12 +2305,12 @@ static bool unpack_canon_ace(files_struct *fsp, static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head) { - canon_ace *list_head = *pp_list_head; + canon_ace *l_head = *pp_list_head; canon_ace *owner_ace = NULL; canon_ace *other_ace = NULL; canon_ace *ace = NULL; - for (ace = list_head; ace; ace = ace->next) { + for (ace = l_head; ace; ace = ace->next) { if (ace->type == SMB_ACL_USER_OBJ) owner_ace = ace; else if (ace->type == SMB_ACL_OTHER) { @@ -2331,16 +2331,16 @@ static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head) */ if (owner_ace) { - DLIST_PROMOTE(list_head, owner_ace); + DLIST_PROMOTE(l_head, owner_ace); } if (other_ace) { - DLIST_DEMOTE(list_head, other_ace, canon_ace *); + DLIST_DEMOTE(l_head, other_ace, canon_ace *); } /* We have probably changed the head of the list. */ - *pp_list_head = list_head; + *pp_list_head = l_head; } /**************************************************************************** @@ -2353,7 +2353,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type) { mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR); - canon_ace *list_head = NULL; + canon_ace *l_head = NULL; canon_ace *ace = NULL; canon_ace *next_ace = NULL; int entry_id = SMB_ACL_FIRST_ENTRY; @@ -2457,14 +2457,14 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, ace->owner_type = owner_type; ace->ace_flags = get_pai_flags(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT)); - DLIST_ADD(list_head, ace); + DLIST_ADD(l_head, ace); } /* * This next call will ensure we have at least a user/group/world set. */ - if (!ensure_canon_entry_valid(&list_head, conn->params, + if (!ensure_canon_entry_valid(&l_head, conn->params, S_ISDIR(psbuf->st_mode), powner, pgroup, psbuf, False)) goto fail; @@ -2476,7 +2476,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default" )); - for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) { + for ( ace_count = 0, ace = l_head; ace; ace = next_ace, ace_count++) { next_ace = ace->next; /* Masks are only applied to entries other than USER_OBJ and OTHER. */ @@ -2484,7 +2484,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, ace->perms &= acl_mask; if (ace->perms == 0) { - DLIST_PROMOTE(list_head, ace); + DLIST_PROMOTE(l_head, ace); } if( DEBUGLVL( 10 ) ) { @@ -2492,15 +2492,15 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, } } - arrange_posix_perms(fname,&list_head ); + arrange_posix_perms(fname,&l_head ); - print_canon_ace_list( "canonicalise_acl: ace entries after arrange", list_head ); + print_canon_ace_list( "canonicalise_acl: ace entries after arrange", l_head ); - return list_head; + return l_head; fail: - free_canon_ace_list(list_head); + free_canon_ace_list(l_head); return NULL; } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 49995d8901..346e8973de 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -212,7 +212,7 @@ static void remove_child_pid(pid_t pid, bool unclean_shutdown) /* a child terminated uncleanly so tickle all processes to see if they can grab any of the pending locks */ - DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", pid)); + DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", (unsigned int)pid)); messaging_send_buf(smbd_messaging_context(), procid_self(), MSG_SMB_BRL_VALIDATE, NULL, 0); message_send_all(smbd_messaging_context(), diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8a09ed39a9..2c29192220 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1352,8 +1352,8 @@ static int shutdown_other_smbds(struct db_record *rec, return 0; } - DEBUG(0,("shutdown_other_smbds: shutting down pid %d " - "(IP %s)\n", procid_to_pid(&crec->pid), ip)); + DEBUG(0,("shutdown_other_smbds: shutting down pid %u " + "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid), ip)); messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN, &data_blob_null); diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index 7c01f5db3a..042f3a98f7 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -194,7 +194,8 @@ static int smb_download_dir(const char *base, const char *name, int resume) } if(chmod(relname, remotestat.st_mode) < 0) { - fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname, remotestat.st_mode); + fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname, + (unsigned int)remotestat.st_mode); smbc_closedir(dirhandle); return 0; } @@ -471,7 +472,8 @@ static int smb_download_file(const char *base, const char *name, int recursive, if(keep_permissions && !send_stdout) { if(fchmod(localhandle, remotestat.st_mode) < 0) { - fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, remotestat.st_mode); + fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, + (unsigned int)remotestat.st_mode); smbc_close(remotehandle); close(localhandle); return 0; diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index be91611bfb..dbe83152dd 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -386,7 +386,7 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx, if (child_pid != 0) { /* parent */ DEBUG(5, ("winbind_msg_validate_cache: child created with " - "pid %d.\n", child_pid)); + "pid %d.\n", (int)child_pid)); return; } diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index 8326aba40a..02d0b5bc4e 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -2625,9 +2625,9 @@ void cache_store_response(pid_t pid, struct winbindd_response *response) return; DEBUG(10, ("Storing response for pid %d, len %d\n", - pid, response->length)); + (int)pid, response->length)); - fstr_sprintf(key_str, "DR/%d", pid); + fstr_sprintf(key_str, "DR/%d", (int)pid); if (tdb_store(wcache->tdb, string_tdb_data(key_str), make_tdb_data((uint8 *)response, sizeof(*response)), TDB_REPLACE) == -1) @@ -2641,7 +2641,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response) DEBUG(10, ("Storing extra data: len=%d\n", (int)(response->length - sizeof(*response)))); - fstr_sprintf(key_str, "DE/%d", pid); + fstr_sprintf(key_str, "DE/%d", (int)pid); if (tdb_store(wcache->tdb, string_tdb_data(key_str), make_tdb_data((uint8 *)response->extra_data.data, response->length - sizeof(*response)), @@ -2651,7 +2651,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response) /* We could not store the extra data, make sure the tdb does not * contain a main record with wrong dangling extra data */ - fstr_sprintf(key_str, "DR/%d", pid); + fstr_sprintf(key_str, "DR/%d", (int)pid); tdb_delete(wcache->tdb, string_tdb_data(key_str)); return; @@ -2665,9 +2665,9 @@ bool cache_retrieve_response(pid_t pid, struct winbindd_response * response) if (!init_wcache()) return false; - DEBUG(10, ("Retrieving response for pid %d\n", pid)); + DEBUG(10, ("Retrieving response for pid %d\n", (int)pid)); - fstr_sprintf(key_str, "DR/%d", pid); + fstr_sprintf(key_str, "DR/%d", (int)pid); data = tdb_fetch(wcache->tdb, string_tdb_data(key_str)); if (data.dptr == NULL) @@ -2689,7 +2689,7 @@ bool cache_retrieve_response(pid_t pid, struct winbindd_response * response) DEBUG(10, ("Retrieving extra data length=%d\n", (int)(response->length - sizeof(*response)))); - fstr_sprintf(key_str, "DE/%d", pid); + fstr_sprintf(key_str, "DE/%d", (int)pid); data = tdb_fetch(wcache->tdb, string_tdb_data(key_str)); if (data.dptr == NULL) { @@ -2716,10 +2716,10 @@ void cache_cleanup_response(pid_t pid) if (!init_wcache()) return; - fstr_sprintf(key_str, "DR/%d", pid); + fstr_sprintf(key_str, "DR/%d", (int)pid); tdb_delete(wcache->tdb, string_tdb_data(key_str)); - fstr_sprintf(key_str, "DE/%d", pid); + fstr_sprintf(key_str, "DE/%d", (int)pid); tdb_delete(wcache->tdb, string_tdb_data(key_str)); return; diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index d40bab94ef..f56a63faa0 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -183,7 +183,7 @@ static void async_request_timeout_handler(struct event_context *ctx, DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. " "Closing connection to it.\n", - state->child_pid )); + (unsigned int)state->child_pid )); /* Deal with the reply - set to error. */ async_reply_recv(private_data, False); -- cgit From b9860043dc092df25d4a39074e106d7367ebbe8f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Feb 2009 11:39:44 +1100 Subject: fixed the event context for net vampire --- source4/utils/net/net_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/utils/net/net_join.c b/source4/utils/net/net_join.c index ad63340089..b0a25bb7c0 100644 --- a/source4/utils/net/net_join.c +++ b/source4/utils/net/net_join.c @@ -126,7 +126,7 @@ int net_vampire(struct net_context *ctx, int argc, const char **argv) domain_name = tmp; - libnetctx = libnet_context_init(NULL, ctx->lp_ctx); + libnetctx = libnet_context_init(ctx->event_ctx, ctx->lp_ctx); if (!libnetctx) { return -1; } -- cgit From 8d63c596a0f512c96f5663c0a9bd49d3c98c6df9 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Mon, 23 Feb 2009 20:46:11 -0800 Subject: Refactored sys_fork() and sys_pid() into shared util library This fixes a bug in 116ce19b, where we didn't clear the pid cache in become_daemon() and thus the /var/run/smbd.pid didn't match the actual pid of the parent process. Currently S4 will clear the pid cache on fork but doesn't yet take advantage of the pid cache by using sys_pid() instead of the direct get_pid(). --- lib/util/become_daemon.c | 6 +++--- lib/util/system.c | 29 +++++++++++++++++++++++++++++ lib/util/util.h | 10 ++++++++++ source3/Makefile.in | 2 +- source3/include/proto.h | 2 -- source3/lib/system.c | 29 ----------------------------- 6 files changed, 43 insertions(+), 35 deletions(-) diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c index 5a97b65407..3d06a4363d 100644 --- a/lib/util/become_daemon.c +++ b/lib/util/become_daemon.c @@ -66,10 +66,10 @@ _PUBLIC_ void close_low_fds(bool stderr_too) Become a daemon, discarding the controlling terminal. ****************************************************************************/ -_PUBLIC_ void become_daemon(bool Fork, bool no_process_group) +_PUBLIC_ void become_daemon(bool do_fork, bool no_process_group) { - if (Fork) { - if (fork()) { + if (do_fork) { + if (sys_fork()) { _exit(0); } } diff --git a/lib/util/system.c b/lib/util/system.c index 9bd1800233..9bf5de1a83 100644 --- a/lib/util/system.c +++ b/lib/util/system.c @@ -88,3 +88,32 @@ _PUBLIC_ struct in_addr sys_inet_makeaddr(int net, int host) return in2; } +/************************************************************************** + Wrapper for fork. Ensures we clear our pid cache. +****************************************************************************/ + +static pid_t mypid = (pid_t)-1; + +_PUBLIC_ pid_t sys_fork(void) +{ + pid_t forkret = fork(); + + if (forkret == (pid_t)0) { + /* Child - reset mypid so sys_getpid does a system call. */ + mypid = (pid_t) -1; + } + + return forkret; +} + +/************************************************************************** + Wrapper for getpid. Ensures we only do a system call *once*. +****************************************************************************/ + +_PUBLIC_ pid_t sys_getpid(void) +{ + if (mypid == (pid_t)-1) + mypid = getpid(); + + return mypid; +} diff --git a/lib/util/util.h b/lib/util/util.h index d3e446f488..27f94cd685 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -134,6 +134,16 @@ apparent reason. _PUBLIC_ struct hostent *sys_gethostbyname(const char *name); _PUBLIC_ struct in_addr sys_inet_makeaddr(int net, int host); +/** + * Wrapper for fork used to invalid pid cache. + **/ +_PUBLIC_ pid_t sys_fork(void); + +/** + * Wrapper for getpid. Ensures we only do a system call *once*. + **/ +_PUBLIC_ pid_t sys_getpid(void); + /* The following definitions come from lib/util/genrand.c */ /** diff --git a/source3/Makefile.in b/source3/Makefile.in index 7564659dd3..a403f143bb 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -339,7 +339,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ ../lib/util/util.o ../lib/util/fsusage.o \ ../lib/util/params.o ../lib/util/talloc_stack.o \ ../lib/util/genrand.o ../lib/util/util_net.o \ - ../lib/util/become_daemon.o + ../lib/util/become_daemon.o ../lib/util/system.o CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index faf47d3844..14241d5ce3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -972,8 +972,6 @@ struct passwd *sys_getpwnam(const char *name); struct passwd *sys_getpwuid(uid_t uid); struct group *sys_getgrnam(const char *name); struct group *sys_getgrgid(gid_t gid); -pid_t sys_fork(void); -pid_t sys_getpid(void); int sys_popen(const char *command); int sys_pclose(int fd); ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size); diff --git a/source3/lib/system.c b/source3/lib/system.c index 8bdc9fa92b..10b55f662d 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -1042,35 +1042,6 @@ static char **extract_args(TALLOC_CTX *mem_ctx, const char *command) return NULL; } -/************************************************************************** - Wrapper for fork. Ensures that mypid is reset. Used so we can write - a sys_getpid() that only does a system call *once*. -****************************************************************************/ - -static pid_t mypid = (pid_t)-1; - -pid_t sys_fork(void) -{ - pid_t forkret = fork(); - - if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */ - mypid = (pid_t) -1; - - return forkret; -} - -/************************************************************************** - Wrapper for getpid. Ensures we only do a system call *once*. -****************************************************************************/ - -pid_t sys_getpid(void) -{ - if (mypid == (pid_t)-1) - mypid = getpid(); - - return mypid; -} - /************************************************************************** Wrapper for popen. Safer as it doesn't search a path. Modified from the glibc sources. -- cgit From 7bcaaf14fbf22805d88b945256b6bd31121c7c66 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sun, 22 Feb 2009 20:50:30 -0800 Subject: s3 OneFS: Add a parameter that unconditionally allows execute access --- source3/modules/onefs.h | 2 ++ source3/modules/onefs_system.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index a70664bbf3..418e13d9d2 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -41,6 +41,8 @@ enum onefs_acl_wire_format #define PARM_ONEFS_TYPE "onefs" #define PARM_ACL_WIRE_FORMAT "acl wire format" #define PARM_ACL_WIRE_FORMAT_DEFAULT ACL_FORMAT_WINDOWS_SD +#define PARM_ALLOW_EXECUTE_ALWAYS "allow execute always" +#define PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT false #define PARM_ATIME_NOW "atime now files" #define PARM_ATIME_NOW_DEFAULT NULL #define PARM_ATIME_STATIC "atime static files" diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 10802895cd..76df006d82 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -132,6 +132,30 @@ int onefs_sys_create_file(connection_struct *conn, if (lp_nt_acl_support(SNUM(conn)) && !lp_inherit_perms(SNUM(conn))) cf_flags = cf_flags_or(cf_flags, CF_FLAGS_DEFAULT_ACL); + /* + * Some customer workflows require the execute bit to be ignored. + */ + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_ALLOW_EXECUTE_ALWAYS, + PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT) && + (open_access_mask & FILE_EXECUTE)) { + + DEBUG(3, ("Stripping execute bit from %s: (0x%x)\n", path, + open_access_mask)); + + /* Strip execute. */ + open_access_mask &= ~FILE_EXECUTE; + + /* + * Add READ_DATA, so we're not left with desired_access=0. An + * execute call should imply the client will read the data. + */ + open_access_mask |= FILE_READ_DATA; + + DEBUGADD(3, ("New stripped access mask: 0x%x\n", + open_access_mask)); + } + DEBUG(10,("onefs_sys_create_file: base_fd = %d, " "open_access_mask = 0x%x, flags = 0x%x, mode = 0%o, " "desired_oplock = %s, id = 0x%x, secinfo = 0x%x, sd = %p, " -- cgit From 997dfbbf5409a9df3b3c87025fa80fb6bdafcac2 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 23 Feb 2009 17:43:47 -0800 Subject: s3 OneFS: Fix a double free in an error path --- source3/smbd/oplock_onefs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c index 0908ce4386..d4f181fc47 100644 --- a/source3/smbd/oplock_onefs.c +++ b/source3/smbd/oplock_onefs.c @@ -744,13 +744,13 @@ struct kernel_oplocks *onefs_init_kernel_oplocks(TALLOC_CTX *mem_ctx) po.po_flags_on |= P_NON_BLOCKING_SEMLOCK; if (setprocoptions(&po) != 0) { DEBUG(0, ("setprocoptions failed: %s.\n", strerror(errno))); - goto err_out; + return NULL; } /* Setup the oplock contexts */ _ctx = talloc_zero(mem_ctx, struct kernel_oplocks); if (!_ctx) { - goto err_out; + return NULL; } ctx = talloc_zero(_ctx, struct onefs_oplocks_context); @@ -788,7 +788,6 @@ struct kernel_oplocks *onefs_init_kernel_oplocks(TALLOC_CTX *mem_ctx) err_out: talloc_free(_ctx); - talloc_free(ctx); return NULL; } -- cgit From 022946d1961ddca40a9ac1fc00cf79ae32797669 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 24 Feb 2009 20:41:50 +1100 Subject: Make the 'modules.conf' generation in the LDAP selftest simpler The versions of OpenLDAP that we require don't need us to specify the location any more - slaptest knows this from it's build time. Andrew Bartlett --- selftest/target/Samba4.pm | 59 ++++++----------------------------------------- 1 file changed, 7 insertions(+), 52 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 09138cf0aa..71dddf6939 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -242,77 +242,32 @@ sub mk_openldap($$$) $ENV{PATH} = "$olpath/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}"; unlink($modconf); - open(CONF, ">$modconf"); close(CONF); - if (system("slaptest -u -f $slapd_conf >&2") != 0) { - open(CONF, ">$modconf"); - # enable slapd modules - print CONF " -modulepath $olroot/libexec/openldap -moduleload syncprov -moduleload memberof -moduleload refint -"; - close(CONF); - } - if (system("slaptest -u -f $slapd_conf >&2") != 0) { - open(CONF, ">$modconf"); - # enable slapd modules - print CONF " -modulepath $olroot/libexec/openldap -moduleload back_hdb -moduleload syncprov -moduleload memberof -moduleload refint -"; - close(CONF); - } + #This code tries to guess what modules we need to load (if any) by trying different combinations in the modules.conf - if (system("slaptest -u -f $slapd_conf >&2") != 0) { - open(CONF, ">$modconf"); - # enable slapd modules - print CONF " -moduleload back_hdb -moduleload syncprov -moduleload memberof -moduleload refint -"; - close(CONF); - } + # Try without any slapd modules + open(CONF, ">$modconf"); close(CONF); if (system("slaptest -u -f $slapd_conf >&2") != 0) { open(CONF, ">$modconf"); # enable slapd modules print CONF " -modulepath /usr/lib/ldap -moduleload back_hdb moduleload syncprov moduleload memberof moduleload refint +moduleload deref "; close(CONF); } - if (system("slaptest -u -f $slapd_conf >&2") != 0) { open(CONF, ">$modconf"); - # enable slapd modules (Fedora layout) + # enable slapd modules, and the module for back_hdb print CONF " -modulepath /usr/lib/openldap -moduleload syncprov -moduleload memberof -moduleload refint -"; - close(CONF); - } - - if (system("slaptest -u -f $slapd_conf >&2") != 0) { - open(CONF, ">$modconf"); - # enable slapd modules (Fedora x86_64 layout) - print CONF " -modulepath /usr/lib64/openldap +moduleload back_hdb moduleload syncprov moduleload memberof moduleload refint +moduleload deref "; close(CONF); } -- cgit From 0ca5b72ad951df5f1cc3be30ca5be87399714dcc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 10:40:21 +0100 Subject: spoolss: add SPOOLSS_DEFAULT_SERVER_PATH. Guenther --- librpc/idl/spoolss.idl | 1 + 1 file changed, 1 insertion(+) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index b8f4c13148..4765dd0b1e 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1118,6 +1118,7 @@ import "misc.idl", "security.idl", "winreg.idl"; /******************/ /* Function: 0x1a */ const string SPOOLSS_ARCHITECTURE_NT_X86 = "Windows NT x86"; + const string SPOOLSS_DEFAULT_SERVER_PATH = "C:\\WINDOWS\\system32\\spool"; typedef [public,gensize] struct { [value(ndr_size_spoolss_OSVersion(r,ndr->iconv_convenience,ndr->flags))] uint32 _ndr_size; -- cgit From aa576c292f6b16ee95e539c921f54f9b07313f17 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 10:41:05 +0100 Subject: spoolss: return subcontext spoolss_DriverInfo in spoolss_GetPrinterDriver2. Guenther --- librpc/idl/spoolss.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 4765dd0b1e..510ad3e8b2 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1505,7 +1505,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [in] uint32 offered, [in] uint32 client_major_version, [in] uint32 client_minor_version, - [out,unique] DATA_BLOB *info, + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_DriverInfo *info, [out,ref] uint32 *needed, [out,ref] uint32 *server_major_version, [out,ref] uint32 *server_minor_version -- cgit From 13995f5212bf1f5db4d246e8de3f63b761788d71 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 10:43:53 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/cli_spoolss.c | 2 +- librpc/gen_ndr/cli_spoolss.h | 2 +- librpc/gen_ndr/ndr_spoolss.c | 19 ++++++++++++++++--- librpc/gen_ndr/spoolss.h | 3 ++- librpc/gen_ndr/srv_spoolss.c | 4 ++-- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c index 02a05b94ff..2aa42b93bf 100644 --- a/librpc/gen_ndr/cli_spoolss.c +++ b/librpc/gen_ndr/cli_spoolss.c @@ -2540,7 +2540,7 @@ NTSTATUS rpccli_spoolss_GetPrinterDriver2(struct rpc_pipe_client *cli, uint32_t offered /* [in] */, uint32_t client_major_version /* [in] */, uint32_t client_minor_version /* [in] */, - DATA_BLOB *info /* [out] [unique] */, + union spoolss_DriverInfo *info /* [out] [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */, uint32_t *needed /* [out] [ref] */, uint32_t *server_major_version /* [out] [ref] */, uint32_t *server_minor_version /* [out] [ref] */, diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h index bb38d59cfb..83b2e28729 100644 --- a/librpc/gen_ndr/cli_spoolss.h +++ b/librpc/gen_ndr/cli_spoolss.h @@ -331,7 +331,7 @@ NTSTATUS rpccli_spoolss_GetPrinterDriver2(struct rpc_pipe_client *cli, uint32_t offered /* [in] */, uint32_t client_major_version /* [in] */, uint32_t client_minor_version /* [in] */, - DATA_BLOB *info /* [out] [unique] */, + union spoolss_DriverInfo *info /* [out] [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */, uint32_t *needed /* [out] [ref] */, uint32_t *server_major_version /* [out] [ref] */, uint32_t *server_minor_version /* [out] [ref] */, diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 3e210b2417..642ac0b71b 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -20096,7 +20096,13 @@ static enum ndr_err_code ndr_push_spoolss_GetPrinterDriver2(struct ndr_push *ndr if (flags & NDR_OUT) { NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.info)); if (r->out.info) { - NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, *r->out.info)); + { + struct ndr_push *_ndr_info; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 4, r->in.offered)); + NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->out.info, r->in.level)); + NDR_CHECK(ndr_push_spoolss_DriverInfo(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->out.info)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 4, r->in.offered)); + } } if (r->out.needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -20188,7 +20194,13 @@ static enum ndr_err_code ndr_pull_spoolss_GetPrinterDriver2(struct ndr_pull *ndr if (r->out.info) { _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0); - NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, r->out.info)); + { + struct ndr_pull *_ndr_info; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 4, r->in.offered)); + NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->out.info, r->in.level)); + NDR_CHECK(ndr_pull_spoolss_DriverInfo(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->out.info)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 4, r->in.offered)); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); } if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { @@ -20255,7 +20267,8 @@ _PUBLIC_ void ndr_print_spoolss_GetPrinterDriver2(struct ndr_print *ndr, const c ndr_print_ptr(ndr, "info", r->out.info); ndr->depth++; if (r->out.info) { - ndr_print_DATA_BLOB(ndr, "info", *r->out.info); + ndr_print_set_switch_value(ndr, r->out.info, r->in.level); + ndr_print_spoolss_DriverInfo(ndr, "info", r->out.info); } ndr->depth--; ndr_print_ptr(ndr, "needed", r->out.needed); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 0e8ba37cb7..0b77997ee4 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -10,6 +10,7 @@ #define PRINTER_ENUM_ICONMASK ( (PRINTER_ENUM_ICON1|PRINTER_ENUM_ICON2|PRINTER_ENUM_ICON3|PRINTER_ENUM_ICON4|PRINTER_ENUM_ICON5|PRINTER_ENUM_ICON6|PRINTER_ENUM_ICON7|PRINTER_ENUM_ICON8) ) #define SPOOLSS_ARCHITECTURE_NT_X86 ( "Windows NT x86" ) +#define SPOOLSS_DEFAULT_SERVER_PATH ( "C:\\WINDOWS\\system32\\spool" ) #define PRINTER_CHANGE_PRINTER ( 0x000000FF ) #define PRINTER_CHANGE_JOB ( 0x0000FF00 ) #define PRINTER_CHANGE_FORM ( (PRINTER_CHANGE_ADD_FORM|PRINTER_CHANGE_SET_FORM|PRINTER_CHANGE_DELETE_FORM) ) @@ -2282,7 +2283,7 @@ struct spoolss_GetPrinterDriver2 { } in; struct { - DATA_BLOB *info;/* [unique] */ + union spoolss_DriverInfo *info;/* [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */ uint32_t *needed;/* [ref] */ uint32_t *server_major_version;/* [ref] */ uint32_t *server_minor_version;/* [ref] */ diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c index f6c17cb1fa..891be85376 100644 --- a/librpc/gen_ndr/srv_spoolss.c +++ b/librpc/gen_ndr/srv_spoolss.c @@ -4169,7 +4169,7 @@ static bool api_spoolss_GetPrinterDriver2(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.info = talloc_zero(r, DATA_BLOB); + r->out.info = talloc_zero(r, union spoolss_DriverInfo); if (r->out.info == NULL) { talloc_free(r); return false; @@ -8080,7 +8080,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_SPOOLSS_GETPRINTERDRIVER2: { struct spoolss_GetPrinterDriver2 *r = (struct spoolss_GetPrinterDriver2 *)_r; ZERO_STRUCT(r->out); - r->out.info = talloc_zero(mem_ctx, DATA_BLOB); + r->out.info = talloc_zero(mem_ctx, union spoolss_DriverInfo); if (r->out.info == NULL) { return NT_STATUS_NO_MEMORY; } -- cgit From 00173c6ce6e6aa394acc0685827b0b9fb1faf45c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 10:34:40 +0100 Subject: s3-spoolss: merge path handling in _spoolss_PrintProcessorDirectory and _spoolss_PrinterDriverDirectory. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 127 ++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 36 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index a4679eb717..62301c001b 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -8059,45 +8059,106 @@ WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p, /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx, +struct _spoolss_paths { + int type; + const char *share; + const char *dir; +}; + +enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH }; + +static const struct _spoolss_paths spoolss_paths[]= { + { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" }, + { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" } +}; + +static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx, const char *servername, const char *environment, - struct spoolss_DriverDirectoryInfo1 *info1, - uint32_t offered, - uint32_t *needed) + int component, + char **path) { - char *path = NULL; const char *pservername = NULL; const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86; const char *short_archi; - if (environment) { + *path = NULL; + + /* environment may be empty */ + if (environment && strlen(environment)) { long_archi = environment; } - pservername = canon_servername(servername); + /* servername may be empty */ + if (servername && strlen(servername)) { + pservername = canon_servername(servername); - if ( !is_myname_or_ipaddr(pservername)) - return WERR_INVALID_PARAM; + if (!is_myname_or_ipaddr(pservername)) { + return WERR_INVALID_PARAM; + } + } - if (!(short_archi = get_short_archi(long_archi))) + if (!(short_archi = get_short_archi(long_archi))) { return WERR_INVALID_ENVIRONMENT; + } - path = talloc_asprintf(mem_ctx, - "\\\\%s\\print$\\%s", pservername, short_archi); - if (!path) { + switch (component) { + case SPOOLSS_PRTPROCS_PATH: + case SPOOLSS_DRIVER_PATH: + if (pservername) { + *path = talloc_asprintf(mem_ctx, + "\\\\%s\\%s\\%s", + pservername, + spoolss_paths[component].share, + short_archi); + } else { + *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s", + SPOOLSS_DEFAULT_SERVER_PATH, + spoolss_paths[component].dir, + short_archi); + } + break; + default: + return WERR_INVALID_PARAM; + } + + if (!*path) { return WERR_NOMEM; } + return WERR_OK; +} + +/**************************************************************************** +****************************************************************************/ + +static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx, + const char *servername, + const char *environment, + struct spoolss_DriverDirectoryInfo1 *r, + uint32_t offered, + uint32_t *needed) +{ + WERROR werr; + char *path = NULL; + + werr = compose_spoolss_server_path(mem_ctx, + servername, + environment, + SPOOLSS_DRIVER_PATH, + &path); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + DEBUG(4,("printer driver directory: [%s]\n", path)); - info1->directory_name = path; + r->directory_name = path; - *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0); + *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0); if (*needed > offered) { talloc_free(path); - ZERO_STRUCTP(info1); return WERR_INSUFFICIENT_BUFFER; } @@ -9728,36 +9789,30 @@ done: static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx, const char *servername, const char *environment, - struct spoolss_PrintProcessorDirectoryInfo1 *info1, + struct spoolss_PrintProcessorDirectoryInfo1 *r, uint32_t offered, uint32_t *needed) { - const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86; - const char *short_archi; - - if (environment) { - long_archi = environment; - } + WERROR werr; + char *path = NULL; - short_archi = get_short_archi(long_archi); - if (!short_archi) { - return WERR_INVALID_ENVIRONMENT; + werr = compose_spoolss_server_path(mem_ctx, + servername, + environment, + SPOOLSS_PRTPROCS_PATH, + &path); + if (!W_ERROR_IS_OK(werr)) { + return werr; } - /* I think this should look like this - gd - info1->directory_name = talloc_asprintf(mem_ctx, - "C:\\WINNT\\System32\\spool\\PRTPROCS\\%s", short_archi); - */ - info1->directory_name = talloc_strdup(mem_ctx, - "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86"); + DEBUG(4,("print processor directory: [%s]\n", path)); - if (!info1->directory_name) { - return WERR_NOMEM; - } + r->directory_name = path; - *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(info1, NULL, 0); + *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0); if (*needed > offered) { + talloc_free(path); return WERR_INSUFFICIENT_BUFFER; } -- cgit From 31f2cddcf5886b0a78290fdfa609a2ee63bda5ad Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Tue, 24 Feb 2009 11:37:58 +1100 Subject: Added mmr and olc to the OpenLDAP backend provisioning-scripts These extensions add mmr (multi-master-replication) and olc (openldap-online-configuration) capabilities to the provisioning-scripts (provision-backend and provision.py), for use with the openldap-backend (only versions >=2.4.15!). Changes / additions made to the provision-backend -script: added new command-line-options: --ol-mmr-urls= for use with mmr (can be combined with --ol-olc=yes), --ol-olc=[yes/no] (activate automatic conversion from static slapd.conf to olc), --ol-slaptest= (needed in conjunction with --ol-olc=yes) Changes / additions made to the provision.py -script: added extensions, that will automatically generate the chosen mmr and/or olc setup for the openldap backend, according to the to chosen parameters set in the provision-backend script Signed-off-by: Andrew Bartlett --- source4/scripting/python/samba/provision.py | 187 ++++++++++++++++++++++------ source4/setup/DB_CONFIG | 11 -- source4/setup/mmr_serverids.conf | 1 - source4/setup/olcOverlay={0}syncprov.ldif | 11 ++ source4/setup/olc_acl.conf | 4 + source4/setup/olc_mmr.conf | 3 + source4/setup/olc_pass.conf | 3 + source4/setup/olc_seed.ldif | 16 +++ source4/setup/olc_serverid.conf | 1 + source4/setup/olc_syncrepl.conf | 13 ++ source4/setup/olc_syncrepl_seed.conf | 5 + source4/setup/provision-backend | 12 +- source4/setup/slapd.conf | 20 +-- 13 files changed, 224 insertions(+), 63 deletions(-) create mode 100644 source4/setup/olcOverlay={0}syncprov.ldif create mode 100644 source4/setup/olc_acl.conf create mode 100644 source4/setup/olc_mmr.conf create mode 100644 source4/setup/olc_pass.conf create mode 100644 source4/setup/olc_seed.ldif create mode 100644 source4/setup/olc_serverid.conf create mode 100644 source4/setup/olc_syncrepl.conf create mode 100644 source4/setup/olc_syncrepl_seed.conf diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a5b3e8322f..8442c24d71 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -26,6 +26,7 @@ from base64 import b64encode import os +import sys import pwd import grp import time @@ -93,9 +94,14 @@ class ProvisionPaths(object): self.memberofconf = None self.fedoradsinf = None self.fedoradspartitions = None - self.olmmron = None - self.olmmrserveridsconf = None - self.olmmrsyncreplconf = None + self.olmmron = None + self.olmmrserveridsconf = None + self.olmmrsyncreplconf = None + self.olcdir = None + self.olslaptest = None + self.olcseedldif = None + self.olcsyncprovdir = None + self.olcsyncprovfile = None class ProvisionNames(object): @@ -268,6 +274,14 @@ def provision_paths_from_lp(lp, dnsdomain): "mmr_serverids.conf") paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, "mmr_syncrepl.conf") + paths.olcdir = os.path.join(paths.ldapdir, + "slapd.d") + paths.olcseedldif = os.path.join(paths.ldapdir, + "olc_seed.ldif") + paths.olcsyncprovdir = os.path.join(paths.olcdir, + "cn=config/olcDatabase={0}config") + paths.olcsyncprovfile = os.path.join(paths.olcsyncprovdir, + "olcOverlay={0}syncprov.ldif") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -1178,7 +1192,7 @@ def provision_backend(setup_dir=None, message=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, ldap_backend_type=None, ldap_backend_port=None, - ol_mmr_urls=None): + ol_mmr_urls=None,ol_olc=None,ol_slaptest=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1205,6 +1219,19 @@ def provision_backend(setup_dir=None, message=None, make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + # openldap-online-configuration: validation of olc and slaptest + if ol_olc == "yes" and ol_slaptest is None: + sys.exit("Warning: OpenLDAP-Online-Configuration cant be setup without path to slaptest-Binary!") + + if ol_olc == "yes" and ol_slaptest is not None: + ol_slaptest = ol_slaptest + "/slaptest" + if not os.path.exists(ol_slaptest): + message (ol_slaptest) + sys.exit("Warning: Given Path to slaptest-Binary does not exist!") + ### + + + lp = param.LoadParm() lp.load(smbconf) @@ -1300,52 +1327,95 @@ def provision_backend(setup_dir=None, message=None, { "LINK_ATTRS" : refint_attributes}) # generate serverids, ldap-urls and syncrepl-blocks for mmr hosts - mmr_on_config = "" - mmr_replicator_acl = "" - mmr_serverids_config = "" + mmr_on_config = "" + mmr_replicator_acl = "" + mmr_serverids_config = "" mmr_syncrepl_schema_config = "" - mmr_syncrepl_config_config = "" - mmr_syncrepl_user_config = "" - - if ol_mmr_urls is not None: + mmr_syncrepl_config_config = "" + mmr_syncrepl_user_config = "" + + + if ol_mmr_urls is not None: # For now, make these equal mmr_pass = adminpass - url_list=filter(None,ol_mmr_urls.split(' ')) + url_list=filter(None,ol_mmr_urls.split(' ')) if (len(url_list) == 1): url_list=filter(None,ol_mmr_urls.split(',')) - mmr_on_config = "MirrorMode On" - mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" - serverid=0 - for url in url_list: - serverid=serverid+1 - mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), - { "SERVERID" : str(serverid), - "LDAPSERVER" : url }) + mmr_on_config = "MirrorMode On" + mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" + serverid=0 + for url in url_list: + serverid=serverid+1 + mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) rid=serverid*10 - rid=rid+1 - mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.schemadn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.schemadn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.configdn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.configdn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.domaindn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.domaindn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass }) + # olc = yes? + olc_config_pass = "" + olc_config_acl = "" + olc_syncrepl_config = "" + olc_mmr_config = "" + if ol_olc == "yes": + olc_config_pass += read_and_sub_file(setup_path("olc_pass.conf"), + { "OLC_PW": adminpass }) + olc_config_acl += read_and_sub_file(setup_path("olc_acl.conf"),{}) + + # if olc = yes + mmr = yes, generate cn=config-replication directives + # and olc_seed.lif for the other mmr-servers + if ol_olc == "yes" and ol_mmr_urls is not None: + serverid=0 + olc_serverids_config = "" + olc_syncrepl_config = "" + olc_syncrepl_seed_config = "" + olc_mmr_config = "" + olc_mmr_config += read_and_sub_file(setup_path("olc_mmr.conf"),{}) + rid=1000 + for url in url_list: + serverid=serverid+1 + olc_serverids_config += read_and_sub_file(setup_path("olc_serverid.conf"), + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) + + rid=rid+1 + olc_syncrepl_config += read_and_sub_file(setup_path("olc_syncrepl.conf"), + { "RID" : str(rid), + "LDAPSERVER" : url, + "MMR_PASSWORD": adminpass}) + + olc_syncrepl_seed_config += read_and_sub_file(setup_path("olc_syncrepl_seed.conf"), + { "RID" : str(rid), + "LDAPSERVER" : url}) + + setup_file(setup_path("olc_seed.ldif"), paths.olcseedldif, + {"OLC_SERVER_ID_CONF": olc_serverids_config, + "OLC_PW": adminpass, + "OLC_SYNCREPL_CONF": olc_syncrepl_seed_config}) + + # end olc setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, @@ -1360,8 +1430,12 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, + "OLC_CONFIG_PASS": olc_config_pass, + "OLC_SYNCREPL_CONFIG": olc_syncrepl_config, + "OLC_CONFIG_ACL": olc_config_acl, + "OLC_MMR_CONFIG": olc_mmr_config, "REFINT_CONFIG": refint_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) @@ -1380,16 +1454,15 @@ def provision_backend(setup_dir=None, message=None, {"LDAPADMINPASS_B64": b64encode(adminpass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) - - if ol_mmr_urls is not None: - setup_file(setup_path("cn=replicator.ldif"), + + if ol_mmr_urls is not None: + setup_file(setup_path("cn=replicator.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), {"MMR_PASSWORD_B64": b64encode(mmr_pass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) - mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" @@ -1399,7 +1472,18 @@ def provision_backend(setup_dir=None, message=None, else: server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + if ol_olc != "yes" and ol_mmr_urls is None: + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + + if ol_olc == "yes" and ol_mmr_urls is None: + slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" + + if ol_olc != "yes" and ol_mmr_urls is not None: + slapdcommand="Start slapd with: slapd -F " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" + + if ol_olc == "yes" and ol_mmr_urls is not None: + slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" + ldapuser = "--username=samba-admin" @@ -1437,6 +1521,27 @@ def provision_backend(setup_dir=None, message=None, message("Run provision with: " + " ".join(args)) + # if --ol-olc=yes, generate online-configuration in ../private/ldap/slapd.d + if ol_olc == "yes": + if not os.path.isdir(paths.olcdir): + os.makedirs(paths.olcdir, 0770) + paths.olslaptest = str(ol_slaptest) + olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir + " >/dev/null 2>&1" + os.system(olc_command) + #os.remove(paths.slapdconf) + # use line below for debugging during olc-conversion with slaptest + #olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir" + + # workaround, if overlay syncprov is was not created properly during conversion to cn=config. + # otherwise, cn=config won't be replicated + if ol_olc == "yes" and ol_mmr_urls is not None: + if not os.path.exists(paths.olcsyncprovdir): + os.makedirs(paths.olcsyncprovdir, 0770) + setup_file(setup_path("olcOverlay={0}syncprov.ldif"), + os.path.join(paths.olcsyncprovdir, "olcOverlay={0}syncprov.ldif"), {}) + + + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. diff --git a/source4/setup/DB_CONFIG b/source4/setup/DB_CONFIG index b4d2bfa868..74bb09d800 100644 --- a/source4/setup/DB_CONFIG +++ b/source4/setup/DB_CONFIG @@ -1,17 +1,6 @@ -# -# Set the database in memory cache size. -# set_cachesize 0 524288 0 - -# -# Set log values. -# set_lg_regionmax 104857 set_lg_max 1048576 set_lg_bsize 209715 set_lg_dir ${LDAPDBDIR}/bdb-logs - -# -# Set temporary file creation directory. -# set_tmp_dir ${LDAPDBDIR}/tmp diff --git a/source4/setup/mmr_serverids.conf b/source4/setup/mmr_serverids.conf index c6d14010b4..e4daf2028a 100644 --- a/source4/setup/mmr_serverids.conf +++ b/source4/setup/mmr_serverids.conf @@ -1,2 +1 @@ -# Generated from template mmr_serverids.conf ServerID ${SERVERID} "${LDAPSERVER}" diff --git a/source4/setup/olcOverlay={0}syncprov.ldif b/source4/setup/olcOverlay={0}syncprov.ldif new file mode 100644 index 0000000000..4f5b513c67 --- /dev/null +++ b/source4/setup/olcOverlay={0}syncprov.ldif @@ -0,0 +1,11 @@ +dn: olcOverlay={0}syncprov +objectClass: olcOverlayConfig +objectClass: olcSyncProvConfig +olcOverlay: {0}syncprov +structuralObjectClass: olcSyncProvConfig +entryUUID: 41df5aca-785a-102d-9077-999999999999 +creatorsName: cn=config +createTimestamp: 20090116201111Z +entryCSN: 20090116201111.111111Z#000000#000#000000 +modifiersName: cn=config +modifyTimestamp: 20090116201111Z diff --git a/source4/setup/olc_acl.conf b/source4/setup/olc_acl.conf new file mode 100644 index 0000000000..c248b30fb5 --- /dev/null +++ b/source4/setup/olc_acl.conf @@ -0,0 +1,4 @@ +access to dn.sub="cn=config" + by dn="cn=samba-admin,cn=samba" write + by dn="cn=replicator,cn=samba" read + diff --git a/source4/setup/olc_mmr.conf b/source4/setup/olc_mmr.conf new file mode 100644 index 0000000000..2f60df1421 --- /dev/null +++ b/source4/setup/olc_mmr.conf @@ -0,0 +1,3 @@ +overlay syncprov +MirrorMode on + diff --git a/source4/setup/olc_pass.conf b/source4/setup/olc_pass.conf new file mode 100644 index 0000000000..4c66c1c43f --- /dev/null +++ b/source4/setup/olc_pass.conf @@ -0,0 +1,3 @@ +database config +rootdn cn=config + diff --git a/source4/setup/olc_seed.ldif b/source4/setup/olc_seed.ldif new file mode 100644 index 0000000000..afc3abe5a0 --- /dev/null +++ b/source4/setup/olc_seed.ldif @@ -0,0 +1,16 @@ +dn: cn=config +objectClass: olcGlobal +cn: config +${OLC_SERVER_ID_CONF} + +dn: olcDatabase={0}config,cn=config +objectClass: olcDatabaseConfig +olcDatabase: {0}config +olcRootDN: cn=config +olcRootPW: ${OLC_PW} +${OLC_SYNCREPL_CONF}olcMirrorMode: TRUE + +dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config +objectClass: olcSyncProvConfig +olcOverlay: syncprov + diff --git a/source4/setup/olc_serverid.conf b/source4/setup/olc_serverid.conf new file mode 100644 index 0000000000..3d28acbfb4 --- /dev/null +++ b/source4/setup/olc_serverid.conf @@ -0,0 +1 @@ +olcServerID: ${SERVERID} "${LDAPSERVER}" diff --git a/source4/setup/olc_syncrepl.conf b/source4/setup/olc_syncrepl.conf new file mode 100644 index 0000000000..fd7a58d03b --- /dev/null +++ b/source4/setup/olc_syncrepl.conf @@ -0,0 +1,13 @@ +# Generated from template olc_syncrepl.conf + +syncrepl rid=${RID} + provider="${LDAPSERVER}" + searchbase="cn=config" + filter="(!(olcDatabase={0}config))" + type=refreshAndPersist + retry="10 +" + bindmethod=sasl + saslmech=DIGEST-MD5 + authcid="replicator" + credentials="${MMR_PASSWORD}" + diff --git a/source4/setup/olc_syncrepl_seed.conf b/source4/setup/olc_syncrepl_seed.conf new file mode 100644 index 0000000000..1833fb9228 --- /dev/null +++ b/source4/setup/olc_syncrepl_seed.conf @@ -0,0 +1,5 @@ +olcSyncRepl: rid=${RID} provider="${LDAPSERVER}" + binddn="cn=config" bindmethod=sasl saslmech=DIGEST-MD5 + authcid="replicator" credentials="linux" + searchbase="cn=config" filter="(!(olcDatabase={0}config))" + type=refreshAndPersist retry="10 +" diff --git a/source4/setup/provision-backend b/source4/setup/provision-backend index eca209cb18..20e4420414 100755 --- a/source4/setup/provision-backend +++ b/source4/setup/provision-backend @@ -65,8 +65,12 @@ parser.add_option("--server-role", type="choice", metavar="ROLE", parser.add_option("--targetdir", type="string", metavar="DIR", help="Set target directory") parser.add_option("--ol-mmr-urls", type="string", metavar="LDAPSERVER", - help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR") - + help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") +parser.add_option("--ol-olc", type="choice", metavar="OPENLDAP-OLC", + help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'", + choices=["yes", "no"]) +parser.add_option("--ol-slaptest", type="string", metavar="SLAPTEST-PATH", + help="Path to slaptest-binary [e.g.:'/usr/local/sbin']. Only for use with --ol-olc='yes'") opts = parser.parse_args()[0] @@ -103,5 +107,7 @@ provision_backend(setup_dir=setup_dir, message=message, smbconf=smbconf, targetd root=opts.root, serverrole=server_role, ldap_backend_type=opts.ldap_backend_type, ldap_backend_port=opts.ldap_backend_port, - ol_mmr_urls=opts.ol_mmr_urls) + ol_mmr_urls=opts.ol_mmr_urls, + ol_olc=opts.ol_olc, + ol_slaptest=opts.ol_slaptest) diff --git a/source4/setup/slapd.conf b/source4/setup/slapd.conf index 506dc504b4..09dffbbfa3 100644 --- a/source4/setup/slapd.conf +++ b/source4/setup/slapd.conf @@ -7,7 +7,6 @@ sizelimit unlimited ${MMR_SERVERIDS_CONFIG} - include ${LDAPDIR}/backend-schema.schema pidfile ${LDAPDIR}/slapd.pid @@ -62,6 +61,13 @@ suffix cn=Samba directory ${LDAPDIR}/db/samba rootdn cn=Manager,cn=Samba +######################################## +## olc - configuration ### +${OLC_CONFIG_PASS} +${OLC_SYNCREPL_CONFIG} +${OLC_MMR_CONFIG} +${OLC_CONFIG_ACL} + ######################################## ### cn=schema ### database hdb @@ -78,10 +84,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=schema Subcontext ### @@ -107,10 +113,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=config Subcontext ### ${MMR_SYNCREPL_CONFIG_CONFIG} @@ -139,10 +145,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=user/base-dn context ### ${MMR_SYNCREPL_USER_CONFIG} -- cgit From f21ae452a008370a4846c8955ac1a8fe1a0acb3c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 11:34:57 +0100 Subject: s3-lib: add marshall_sec_desc_buf and unmarshall_sec_desc_buf helpers. Guenther --- source3/include/proto.h | 5 ++++ source3/lib/secdesc.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 14241d5ce3..3ca94b9192 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -695,8 +695,13 @@ SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src); NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx, struct security_descriptor *secdesc, uint8 **data, size_t *len); +NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx, + struct sec_desc_buf *secdesc_buf, + uint8_t **data, size_t *len); NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len, struct security_descriptor **psecdesc); +NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len, + struct sec_desc_buf **psecdesc_buf); SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid, SEC_ACL *dacl, size_t *sd_size); SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc); diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index 232bbca43c..a81c4ae82a 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -290,6 +290,32 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +/******************************************************************* + Convert a secdesc_buf into a byte stream +********************************************************************/ + +NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx, + struct sec_desc_buf *secdesc_buf, + uint8_t **data, size_t *len) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + + ndr_err = ndr_push_struct_blob( + &blob, mem_ctx, NULL, secdesc_buf, + (ndr_push_flags_fn_t)ndr_push_sec_desc_buf); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_push_sec_desc_buf failed: %s\n", + ndr_errstr(ndr_err))); + return ndr_map_error2ntstatus(ndr_err);; + } + + *data = blob.data; + *len = blob.length; + return NT_STATUS_OK; +} + /******************************************************************* Parse a byte stream into a secdesc ********************************************************************/ @@ -326,6 +352,43 @@ NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len, return NT_STATUS_OK; } +/******************************************************************* + Parse a byte stream into a sec_desc_buf +********************************************************************/ + +NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len, + struct sec_desc_buf **psecdesc_buf) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + struct sec_desc_buf *result; + + if ((data == NULL) || (len == 0)) { + return NT_STATUS_INVALID_PARAMETER; + } + + result = TALLOC_ZERO_P(mem_ctx, struct sec_desc_buf); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + blob = data_blob_const(data, len); + + ndr_err = ndr_pull_struct_blob( + &blob, result, NULL, result, + (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_pull_sec_desc_buf failed: %s\n", + ndr_errstr(ndr_err))); + TALLOC_FREE(result); + return ndr_map_error2ntstatus(ndr_err);; + } + + *psecdesc_buf = result; + return NT_STATUS_OK; +} + /******************************************************************* Creates a SEC_DESC structure with typical defaults. ********************************************************************/ -- cgit From e1749a1f7815dae4f0721a62a0ea5d3a88aaf320 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 12:19:01 +0100 Subject: s3-spoolss: use marshall/unmarshall_sec_desc_buf in nt_printing_setsec/getsec. Guenther --- source3/printing/nt_printing.c | 80 ++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index ad3a95826a..bbe8ebc2bc 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -5408,11 +5408,12 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) { SEC_DESC_BUF *new_secdesc_ctr = NULL; SEC_DESC_BUF *old_secdesc_ctr = NULL; - prs_struct ps; - bool prs_init_done = false; TALLOC_CTX *mem_ctx = NULL; TDB_DATA kbuf; + TDB_DATA dbuf; + DATA_BLOB blob; WERROR status; + NTSTATUS nt_status; mem_ctx = talloc_init("nt_printing_setsec"); if (mem_ctx == NULL) @@ -5474,26 +5475,19 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) /* Store the security descriptor in a tdb */ - if (!prs_init(&ps, - (uint32_t)ndr_size_security_descriptor(new_secdesc_ctr->sd, - NULL, 0) - + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL) ) { - status = WERR_NOMEM; - goto out; - } - - - prs_init_done = true; - - if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr, - &ps, 1)) { - status = WERR_BADFUNC; + nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr, + &blob.data, &blob.length); + if (!NT_STATUS_IS_OK(nt_status)) { + status = ntstatus_to_werror(nt_status); goto out; } kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename ); - if (tdb_prs_store(tdb_printers, kbuf, &ps)==0) { + dbuf.dptr = (unsigned char *)blob.data; + dbuf.dsize = blob.length; + + if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) { status = WERR_OK; } else { DEBUG(1,("Failed to store secdesc for %s\n", sharename)); @@ -5501,12 +5495,10 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) } /* Free malloc'ed memory */ + talloc_free(blob.data); out: - if (prs_init_done) { - prs_mem_free(&ps); - } if (mem_ctx) talloc_destroy(mem_ctx); return status; @@ -5602,47 +5594,45 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx) bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr) { - prs_struct ps; TDB_DATA kbuf; + TDB_DATA dbuf; + DATA_BLOB blob; char *temp; + NTSTATUS status; if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) { sharename = temp + 1; } - ZERO_STRUCT(ps); - /* Fetch security descriptor from tdb */ - kbuf = make_printers_secdesc_tdbkey(ctx, sharename ); - - if (tdb_prs_fetch(tdb_printers, kbuf, &ps, ctx)!=0 || - !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) { - - prs_mem_free(&ps); - - DEBUG(4,("using default secdesc for %s\n", sharename)); + kbuf = make_printers_secdesc_tdbkey(ctx, sharename); - if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) { - return False; - } - - /* Save default security descriptor for later */ + dbuf = tdb_fetch(tdb_printers, kbuf); + if (dbuf.dptr) { - if (!prs_init(&ps, (uint32_t)ndr_size_security_descriptor((*secdesc_ctr)->sd, NULL, 0) + - sizeof(SEC_DESC_BUF), ctx, MARSHALL)) - return False; + status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize, + secdesc_ctr); + SAFE_FREE(dbuf.dptr); - if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) { - tdb_prs_store(tdb_printers, kbuf, &ps); + if (NT_STATUS_IS_OK(status)) { + return true; } + } - prs_mem_free(&ps); - - return True; + *secdesc_ctr = construct_default_printer_sdb(ctx); + if (!*secdesc_ctr) { + return false; } - prs_mem_free(&ps); + status = marshall_sec_desc_buf(ctx, *secdesc_ctr, + &blob.data, &blob.length); + if (NT_STATUS_IS_OK(status)) { + dbuf.dptr = (unsigned char *)blob.data; + dbuf.dsize = blob.length; + tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE); + talloc_free(blob.data); + } /* If security descriptor is owned by S-1-1-0 and winbindd is up, this security descriptor has been created when winbindd was -- cgit From 5c5ce2bee68c4f90a0de3f1833d37cf6f71aa867 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 12:37:04 +0100 Subject: spoolss: fix _spoolss_SetPrinter level 3. Guenther --- librpc/idl/spoolss.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 510ad3e8b2..3e35399f8d 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -552,7 +552,7 @@ import "misc.idl", "security.idl", "winreg.idl"; } spoolss_SetPrinterInfo2; typedef struct { - security_descriptor *secdesc; + uint32 sec_desc_ptr; } spoolss_SetPrinterInfo3; typedef struct { -- cgit From 89c682c4185acbf5de16cb4132e33ea825527f41 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 12:38:53 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 31 +++++-------------------------- librpc/gen_ndr/spoolss.h | 2 +- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 642ac0b71b..fdafa2582b 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -3867,36 +3867,20 @@ static enum ndr_err_code ndr_push_spoolss_SetPrinterInfo3(struct ndr_push *ndr, { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_unique_ptr(ndr, r->secdesc)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sec_desc_ptr)); } if (ndr_flags & NDR_BUFFERS) { - if (r->secdesc) { - NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); - } } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_spoolss_SetPrinterInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_SetPrinterInfo3 *r) { - uint32_t _ptr_secdesc; - TALLOC_CTX *_mem_save_secdesc_0; if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_secdesc)); - if (_ptr_secdesc) { - NDR_PULL_ALLOC(ndr, r->secdesc); - } else { - r->secdesc = NULL; - } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sec_desc_ptr)); } if (ndr_flags & NDR_BUFFERS) { - if (r->secdesc) { - _mem_save_secdesc_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->secdesc, 0); - NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_secdesc_0, 0); - } } return NDR_ERR_SUCCESS; } @@ -3905,12 +3889,7 @@ _PUBLIC_ void ndr_print_spoolss_SetPrinterInfo3(struct ndr_print *ndr, const cha { ndr_print_struct(ndr, name, "spoolss_SetPrinterInfo3"); ndr->depth++; - ndr_print_ptr(ndr, "secdesc", r->secdesc); - ndr->depth++; - if (r->secdesc) { - ndr_print_security_descriptor(ndr, "secdesc", r->secdesc); - } - ndr->depth--; + ndr_print_uint32(ndr, "sec_desc_ptr", r->sec_desc_ptr); ndr->depth--; } @@ -4279,7 +4258,7 @@ static enum ndr_err_code ndr_push_spoolss_SetPrinterInfo(struct ndr_push *ndr, i case 3: if (r->info3) { - NDR_CHECK(ndr_push_spoolss_SetPrinterInfo3(ndr, NDR_SCALARS|NDR_BUFFERS, r->info3)); + NDR_CHECK(ndr_push_spoolss_SetPrinterInfo3(ndr, NDR_SCALARS, r->info3)); } break; @@ -4486,7 +4465,7 @@ static enum ndr_err_code ndr_pull_spoolss_SetPrinterInfo(struct ndr_pull *ndr, i if (r->info3) { _mem_save_info3_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->info3, 0); - NDR_CHECK(ndr_pull_spoolss_SetPrinterInfo3(ndr, NDR_SCALARS|NDR_BUFFERS, r->info3)); + NDR_CHECK(ndr_pull_spoolss_SetPrinterInfo3(ndr, NDR_SCALARS, r->info3)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info3_0, 0); } break; diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 0b77997ee4..ad4554dbe5 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -501,7 +501,7 @@ struct spoolss_SetPrinterInfo2 { }; struct spoolss_SetPrinterInfo3 { - struct security_descriptor *secdesc;/* [unique] */ + uint32_t sec_desc_ptr; }; struct spoolss_SetPrinterInfo4 { -- cgit From 6e16c5eed59bb3539af365d30e9ec35012b8c8ac Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 16:57:30 +0100 Subject: s3:mount.cifs: don't error exit on explicitly requested help... Michael --- source3/client/mount.cifs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index a736609580..641584947f 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -179,7 +179,6 @@ static void mount_cifs_usage(void) printf("\n\t%s -V\n",thisprogram); SAFE_FREE(mountpassword); - exit(EX_USAGE); } /* caller frees username if necessary */ @@ -1102,7 +1101,7 @@ int main(int argc, char ** argv) case '?': case 'h': /* help */ mount_cifs_usage (); - exit(EX_USAGE); + exit(0); case 'n': ++nomtab; break; -- cgit From d7ca4997017e86b6f23ced64f1f1672bfb15716b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 16:58:33 +0100 Subject: s3:mount.cifs: make "mount.cifs -V" print the version, not usage. Also make "mount.cifs -h" not exit with error exit code but with return code 0. Michael --- source3/client/mount.cifs.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 641584947f..ae8a7fd186 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -1016,6 +1016,14 @@ uppercase_string(char *string) return 1; } +static void print_cifs_mount_version(void) +{ + printf("mount.cifs version: %s.%s%s\n", + MOUNT_CIFS_VERSION_MAJOR, + MOUNT_CIFS_VERSION_MINOR, + MOUNT_CIFS_VENDOR_SUFFIX); +} + int main(int argc, char ** argv) { int c; @@ -1077,6 +1085,24 @@ int main(int argc, char ** argv) exit(EX_SYSERR); } mountpoint = argv[2]; + } else if (argc == 2) { + if ((strcmp(argv[1], "-V") == 0) || + (strcmp(argv[1], "--version") == 0)) + { + print_cifs_mount_version(); + exit(0); + } + + if ((strcmp(argv[1], "-h") == 0) || + (strcmp(argv[1], "-?") == 0) || + (strcmp(argv[1], "--help") == 0)) + { + mount_cifs_usage(); + exit(0); + } + + mount_cifs_usage(); + exit(EX_USAGE); } else { mount_cifs_usage(); exit(EX_USAGE); @@ -1133,11 +1159,8 @@ int main(int argc, char ** argv) case 'v': ++verboseflag; break; - case 'V': - printf ("mount.cifs version: %s.%s%s\n", - MOUNT_CIFS_VERSION_MAJOR, - MOUNT_CIFS_VERSION_MINOR, - MOUNT_CIFS_VENDOR_SUFFIX); + case 'V': + print_cifs_mount_version(); exit (0); case 'w': flags &= ~MS_RDONLY; -- cgit From dc03a328d8ff55df30a5b996b4a17e82db29708b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 15:28:54 +0100 Subject: s3:example/VFS: fix the build metze --- examples/VFS/skel_opaque.c | 6 ++++-- examples/VFS/skel_transparent.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 5845f62e34..118a5b9da7 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -85,9 +85,11 @@ static SMB_STRUCT_DIR *skel_opendir(vfs_handle_struct *handle, const char *fnam return vfswrap_opendir(NULL, fname, mask, attr); } -static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { - return vfswrap_readdir(NULL, dirp); + return vfswrap_readdir(NULL, dirp, sbuf); } static void skel_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset) diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 7036c730dd..a95b5ae6cd 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -79,9 +79,11 @@ static SMB_STRUCT_DIR *skel_opendir(vfs_handle_struct *handle, const char *fnam return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); } -static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { - return SMB_VFS_NEXT_READDIR(handle, dirp); + return SMB_VFS_NEXT_READDIR(handle, dirp, sbuf); } static void skel_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset) -- cgit From d1922725c66c9f4de25c1d664ae03c90e6c098fb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 14:06:27 +0100 Subject: s3: remove unused smb_ldap.h metze --- source3/include/includes.h | 2 - source3/include/smb_ldap.h | 255 --------------------------------------------- 2 files changed, 257 deletions(-) delete mode 100644 source3/include/smb_ldap.h diff --git a/source3/include/includes.h b/source3/include/includes.h index 5ab5564e47..80d7bfc6cf 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -677,8 +677,6 @@ struct printjob; #include "smbldap.h" -#include "smb_ldap.h" - /* * Reasons for cache flush. */ diff --git a/source3/include/smb_ldap.h b/source3/include/smb_ldap.h deleted file mode 100644 index a3c270d95c..0000000000 --- a/source3/include/smb_ldap.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - Unix SMB/CIFS Implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Volker Lendecke 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - -#ifndef _SMB_LDAP_H -#define _SMB_LDAP_H - -enum ldap_request_tag { - LDAP_TAG_BindRequest = 0, - LDAP_TAG_BindResponse = 1, - LDAP_TAG_UnbindRequest = 2, - LDAP_TAG_SearchRequest = 3, - LDAP_TAG_SearchResultEntry = 4, - LDAP_TAG_SearchResultDone = 5, - LDAP_TAG_ModifyRequest = 6, - LDAP_TAG_ModifyResponse = 7, - LDAP_TAG_AddRequest = 8, - LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, - LDAP_TAG_ModifyDNRequest = 12, - LDAP_TAG_ModifyDNResponse = 13, - LDAP_TAG_CompareRequest = 14, - LDAP_TAG_CompareResponse = 15, - LDAP_TAG_AbandonRequest = 16, - LDAP_TAG_SearchResultReference = 19, - LDAP_TAG_ExtendedRequest = 23, - LDAP_TAG_ExtendedResponse = 24 -}; - -enum ldap_auth_mechanism { - LDAP_AUTH_MECH_SIMPLE = 0, - LDAP_AUTH_MECH_SASL = 3 -}; - -#ifndef LDAP_SUCCESS -enum ldap_result_code { - LDAP_SUCCESS = 0, - LDAP_SASL_BIND_IN_PROGRESS = 0x0e, - LDAP_INVALID_CREDENTIALS = 0x31, - LDAP_OTHER = 0x50 -}; -#endif /* LDAP_SUCCESS */ - -struct ldap_Result { - int resultcode; - const char *dn; - const char *errormessage; - const char *referral; -}; - -struct ldap_attribute { - const char *name; - int num_values; - DATA_BLOB *values; -}; - -struct ldap_BindRequest { - int version; - const char *dn; - enum ldap_auth_mechanism mechanism; - union { - const char *password; - struct { - const char *mechanism; - DATA_BLOB secblob; - } SASL; - } creds; -}; - -struct ldap_BindResponse { - struct ldap_Result response; - union { - DATA_BLOB secblob; - } SASL; -}; - -struct ldap_UnbindRequest { - uint8 __dummy; -}; - -enum ldap_scope { - LDAP_SEARCH_SCOPE_BASE = 0, - LDAP_SEARCH_SCOPE_SINGLE = 1, - LDAP_SEARCH_SCOPE_SUB = 2 -}; - -enum ldap_deref { - LDAP_DEREFERENCE_NEVER = 0, - LDAP_DEREFERENCE_IN_SEARCHING = 1, - LDAP_DEREFERENCE_FINDING_BASE = 2, - LDAP_DEREFERENCE_ALWAYS -}; - -struct ldap_SearchRequest { - const char *basedn; - enum ldap_scope scope; - enum ldap_deref deref; - uint32 timelimit; - uint32 sizelimit; - bool attributesonly; - char *filter; - int num_attributes; - const char **attributes; -}; - -struct ldap_SearchResEntry { - const char *dn; - int num_attributes; - struct ldap_attribute *attributes; -}; - -struct ldap_SearchResRef { - int num_referrals; - const char **referrals; -}; - -enum ldap_modify_type { - LDAP_MODIFY_NONE = -1, - LDAP_MODIFY_ADD = 0, - LDAP_MODIFY_DELETE = 1, - LDAP_MODIFY_REPLACE = 2 -}; - -struct ldap_mod { - enum ldap_modify_type type; - struct ldap_attribute attrib; -}; - -struct ldap_ModifyRequest { - const char *dn; - int num_mods; - struct ldap_mod *mods; -}; - -struct ldap_AddRequest { - const char *dn; - int num_attributes; - struct ldap_attribute *attributes; -}; - -struct ldap_DelRequest { - const char *dn; -}; - -struct ldap_ModifyDNRequest { - const char *dn; - const char *newrdn; - bool deleteolddn; - const char *newsuperior; -}; - -struct ldap_CompareRequest { - const char *dn; - const char *attribute; - const char *value; -}; - -struct ldap_AbandonRequest { - uint32 messageid; -}; - -struct ldap_ExtendedRequest { - const char *oid; - DATA_BLOB value; -}; - -struct ldap_ExtendedResponse { - struct ldap_Result response; - const char *name; - DATA_BLOB value; -}; - -union ldap_Request { - struct ldap_BindRequest BindRequest; - struct ldap_BindResponse BindResponse; - struct ldap_UnbindRequest UnbindRequest; - struct ldap_SearchRequest SearchRequest; - struct ldap_SearchResEntry SearchResultEntry; - struct ldap_Result SearchResultDone; - struct ldap_SearchResRef SearchResultReference; - struct ldap_ModifyRequest ModifyRequest; - struct ldap_Result ModifyResponse; - struct ldap_AddRequest AddRequest; - struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; - struct ldap_ModifyDNRequest ModifyDNRequest; - struct ldap_Result ModifyDNResponse; - struct ldap_CompareRequest CompareRequest; - struct ldap_Result CompareResponse; - struct ldap_AbandonRequest AbandonRequest; - struct ldap_ExtendedRequest ExtendedRequest; - struct ldap_ExtendedResponse ExtendedResponse; -}; - -struct ldap_Control { - const char *oid; - bool critical; - DATA_BLOB value; -}; - -struct ldap_message { - TALLOC_CTX *mem_ctx; - uint32 messageid; - uint8 type; - union ldap_Request r; - int num_controls; - struct ldap_Control *controls; -}; - -struct ldap_queue_entry { - struct ldap_queue_entry *next, *prev; - int msgid; - struct ldap_message *msg; -}; - -struct ldap_connection { - TALLOC_CTX *mem_ctx; - int sock; - int next_msgid; - char *host; - uint16 port; - bool ldaps; - - const char *auth_dn; - const char *simple_pw; - - /* Current outstanding search entry */ - int searchid; - - /* List for incoming search entries */ - struct ldap_queue_entry *search_entries; - - /* Outstanding LDAP requests that have not yet been replied to */ - struct ldap_queue_entry *outstanding; -}; - -#endif -- cgit From 12184d413205d2ad7cbb9e1aaf2db97c7bcb4fc2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 11:40:18 +0100 Subject: s4:libcli: split out LIBCLI_LDAP_MESSAGE subsystem metze --- source4/headermap.txt | 1 + source4/libcli/ldap/config.mk | 21 +- source4/libcli/ldap/ldap.c | 1411 ---------------------------------- source4/libcli/ldap/ldap.h | 191 +---- source4/libcli/ldap/ldap_message.c | 1468 ++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_message.h | 225 ++++++ source4/libcli/ldap/ldap_msg.c | 87 --- 7 files changed, 1709 insertions(+), 1695 deletions(-) delete mode 100644 source4/libcli/ldap/ldap.c create mode 100644 source4/libcli/ldap/ldap_message.c create mode 100644 source4/libcli/ldap/ldap_message.h delete mode 100644 source4/libcli/ldap/ldap_msg.c diff --git a/source4/headermap.txt b/source4/headermap.txt index 8f3749a3b5..8a968315bf 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -49,6 +49,7 @@ param/share.h: share.h ../lib/util/util_tdb.h: util_tdb.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h +libcli/ldap/ldap_message.h: ldap_message.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 2708c66b68..a0e178ac40 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,14 +1,20 @@ +[SUBSYSTEM::LIBCLI_LDAP_MESSAGE] +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB +PRIVATE_DEPENDENCIES = ASN1_UTIL + +LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ + ldap_message.o) +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_message.h + [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS ASN1_UTIL \ - LDAP_ENCODE LIBNDR LP_RESOLVE gensec +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ + LDAP_ENCODE LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ - ldap.o ldap_client.o ldap_bind.o \ - ldap_msg.o ldap_ildap.o ldap_controls.o) - - -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h + ldap_client.o ldap_bind.o \ + ldap_ildap.o ldap_controls.o) +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c))) @@ -16,3 +22,4 @@ $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_L PRIVATE_DEPENDENCIES = LIBLDB LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_ndr.h diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c deleted file mode 100644 index 7a65cc5c27..0000000000 --- a/source4/libcli/ldap/ldap.c +++ /dev/null @@ -1,1411 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - -#include "includes.h" -#include "../lib/util/asn1.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_proto.h" - - -static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) -{ - int i; - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); - for (i=0; iu.list.num_elements; i++) { - if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return false; - } - } - asn1_pop_tag(data); - break; - - case LDB_OP_NOT: - asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.isnot.child)) { - return false; - } - asn1_pop_tag(data); - break; - - case LDB_OP_EQUALITY: - /* equality test */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, tree->u.equality.attr, - strlen(tree->u.equality.attr)); - asn1_write_OctetString(data, tree->u.equality.value.data, - tree->u.equality.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_SUBSTRING: - /* - SubstringFilter ::= SEQUENCE { - type AttributeDescription, - -- at least one must be present - substrings SEQUENCE OF CHOICE { - initial [0] LDAPString, - any [1] LDAPString, - final [2] LDAPString } } - */ - asn1_push_tag(data, ASN1_CONTEXT(4)); - asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - i = 0; - if ( ! tree->u.substring.start_with_wildcard) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - while (tree->u.substring.chunks[i]) { - int ctx; - - if (( ! tree->u.substring.chunks[i + 1]) && - (tree->u.substring.end_with_wildcard == 0)) { - ctx = 2; - } else { - ctx = 1; - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - case LDB_OP_GREATER: - /* greaterOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(5)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_LESS: - /* lessOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(6)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_PRESENT: - /* present test */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); - asn1_write_LDAPString(data, tree->u.present.attr); - asn1_pop_tag(data); - return !data->has_error; - - case LDB_OP_APPROX: - /* approx test */ - asn1_push_tag(data, ASN1_CONTEXT(8)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_EXTENDED: - /* - MatchingRuleAssertion ::= SEQUENCE { - matchingRule [1] MatchingRuleID OPTIONAL, - type [2] AttributeDescription OPTIONAL, - matchValue [3] AssertionValue, - dnAttributes [4] BOOLEAN DEFAULT FALSE - } - */ - asn1_push_tag(data, ASN1_CONTEXT(9)); - if (tree->u.extended.rule_id) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write_LDAPString(data, tree->u.extended.rule_id); - asn1_pop_tag(data); - } - if (tree->u.extended.attr) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_write_LDAPString(data, tree->u.extended.attr); - asn1_pop_tag(data); - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); - asn1_pop_tag(data); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_write_uint8(data, tree->u.extended.dnAttributes); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - default: - return false; - } - return !data->has_error; -} - -static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) -{ - asn1_write_enumerated(data, result->resultcode); - asn1_write_OctetString(data, result->dn, - (result->dn) ? strlen(result->dn) : 0); - asn1_write_OctetString(data, result->errormessage, - (result->errormessage) ? - strlen(result->errormessage) : 0); - if (result->referral) { - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, result->referral, - strlen(result->referral)); - asn1_pop_tag(data); - } -} - -_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) -{ - struct asn1_data *data = asn1_init(mem_ctx); - int i, j; - - if (!data) return false; - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_Integer(data, msg->messageid); - - switch (msg->type) { - case LDAP_TAG_BindRequest: { - struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_Integer(data, r->version); - asn1_write_OctetString(data, r->dn, - (r->dn != NULL) ? strlen(r->dn) : 0); - - switch (r->mechanism) { - case LDAP_AUTH_MECH_SIMPLE: - /* context, primitive */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->creds.password, - strlen(r->creds.password)); - asn1_pop_tag(data); - break; - case LDAP_AUTH_MECH_SASL: - /* context, constructed */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, r->creds.SASL.mechanism, - strlen(r->creds.SASL.mechanism)); - if (r->creds.SASL.secblob) { - asn1_write_OctetString(data, r->creds.SASL.secblob->data, - r->creds.SASL.secblob->length); - } - asn1_pop_tag(data); - break; - default: - return false; - } - - asn1_pop_tag(data); - break; - } - case LDAP_TAG_BindResponse: { - struct ldap_BindResponse *r = &msg->r.BindResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->SASL.secblob) { - asn1_write_ContextSimple(data, 7, r->SASL.secblob); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_UnbindRequest: { -/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ - break; - } - case LDAP_TAG_SearchRequest: { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); - asn1_write_enumerated(data, r->scope); - asn1_write_enumerated(data, r->deref); - asn1_write_Integer(data, r->sizelimit); - asn1_write_Integer(data, r->timelimit); - asn1_write_BOOLEAN(data, r->attributesonly); - - if (!ldap_push_filter(data, r->tree)) { - return false; - } - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - asn1_write_OctetString(data, r->attributes[i], - strlen(r->attributes[i])); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultEntry: { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attr = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attr->name, - strlen(attr->name)); - asn1_push_tag(data, ASN1_SEQUENCE(1)); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attr->values[j].data, - attr->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultDone: { - struct ldap_Result *r = &msg->r.SearchResultDone; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyRequest: { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_mods; i++) { - struct ldb_message_element *attrib = &r->mods[i].attrib; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_enumerated(data, r->mods[i].type); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - - } - asn1_pop_tag(data); - asn1_pop_tag(data); - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyResponse: { - struct ldap_Result *r = &msg->r.ModifyResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddRequest: { - struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attrib = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jattributes[i].num_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddResponse: { - struct ldap_Result *r = &msg->r.AddResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelRequest: { - struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write(data, r->dn, strlen(r->dn)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelResponse: { - struct ldap_Result *r = &msg->r.DelResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNRequest: { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN(data, r->deleteolddn); - if (r->newsuperior) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->newsuperior, - strlen(r->newsuperior)); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareRequest: { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, r->attribute, - strlen(r->attribute)); - asn1_write_OctetString(data, r->value.data, - r->value.length); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AbandonRequest: { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write_implicit_Integer(data, r->messageid); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultReference: { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->referral, strlen(r->referral)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedRequest: { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedResponse: { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->oid) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - } - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - default: - return false; - } - - if (msg->controls != NULL) { - asn1_push_tag(data, ASN1_CONTEXT(0)); - - for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { - return false; - } - } - - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - - if (data->has_error) { - asn1_free(data); - return false; - } - - *result = data_blob_talloc(mem_ctx, data->data, data->length); - asn1_free(data); - return true; -} - -static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, - DATA_BLOB blob) -{ - char *result = talloc_array(mem_ctx, char, blob.length+1); - memcpy(result, blob.data, blob.length); - result[blob.length] = '\0'; - return result; -} - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result) -{ - DATA_BLOB string; - if (!asn1_read_OctetString(data, mem_ctx, &string)) - return false; - *result = blob2string_talloc(mem_ctx, string); - data_blob_free(&string); - return true; -} - -static void ldap_decode_response(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - struct ldap_Result *result) -{ - asn1_read_enumerated(data, &result->resultcode); - asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); - asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { - asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); - asn1_end_tag(data); - } else { - result->referral = NULL; - } -} - -static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) -{ - - chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); - if (chunks == NULL) { - return NULL; - } - - chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); - if (chunks[chunk_num] == NULL) { - return NULL; - } - - chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); - if (chunks[chunk_num]->data == NULL) { - return NULL; - } - chunks[chunk_num]->length = strlen(value); - - chunks[chunk_num + 1] = '\0'; - - return chunks; -} - - -/* - parse the ASN.1 formatted search string into a ldb_parse_tree -*/ -static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, - struct asn1_data *data) -{ - uint8_t filter_tag; - struct ldb_parse_tree *ret; - - if (!asn1_peek_uint8(data, &filter_tag)) { - return NULL; - } - - filter_tag &= 0x1f; /* strip off the asn1 stuff */ - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (ret == NULL) return NULL; - - switch(filter_tag) { - case 0: - case 1: - /* AND or OR of one or more filters */ - ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; - ret->u.list.num_elements = 0; - ret->u.list.elements = NULL; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - while (asn1_tag_remaining(data) > 0) { - struct ldb_parse_tree *subtree; - subtree = ldap_decode_filter_tree(ret, data); - if (subtree == NULL) { - goto failed; - } - ret->u.list.elements = - talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements+1); - if (ret->u.list.elements == NULL) { - goto failed; - } - talloc_steal(ret->u.list.elements, subtree); - ret->u.list.elements[ret->u.list.num_elements] = subtree; - ret->u.list.num_elements++; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 2: - /* 'not' operation */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldap_decode_filter_tree(ret, data); - if (ret->u.isnot.child == NULL) { - goto failed; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 3: { - /* equalityMatch */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attrib); - ret->u.equality.value.data = talloc_steal(ret, value.data); - ret->u.equality.value.length = value.length; - break; - } - case 4: { - /* substrings */ - DATA_BLOB attr; - uint8_t subs_tag; - char *value; - int chunk_num = 0; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); - ret->u.substring.chunks = NULL; - ret->u.substring.start_with_wildcard = 1; - ret->u.substring.end_with_wildcard = 1; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - goto failed; - } - - while (asn1_tag_remaining(data)) { - asn1_peek_uint8(data, &subs_tag); - subs_tag &= 0x1f; /* strip off the asn1 stuff */ - if (subs_tag > 2) goto failed; - - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); - asn1_read_LDAPString(data, mem_ctx, &value); - asn1_end_tag(data); - - switch (subs_tag) { - case 0: - if (ret->u.substring.chunks != NULL) { - /* initial value found in the middle */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.start_with_wildcard = 0; - chunk_num = 1; - break; - - case 1: - if (ret->u.substring.end_with_wildcard == 0) { - /* "any" value found after a "final" value */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - chunk_num++; - break; - - case 2: - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.end_with_wildcard = 0; - break; - - default: - goto failed; - } - - } - - if (!asn1_end_tag(data)) { /* SEQUENCE */ - goto failed; - } - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 5: { - /* greaterOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 6: { - /* lessOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 7: { - /* Normal presence, "attribute=*" */ - char *attr; - - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { - goto failed; - } - if (!asn1_read_LDAPString(data, ret, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = talloc_steal(ret, attr); - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 8: { - /* approx */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 9: { - char *oid = NULL, *attr = NULL, *value; - uint8_t dnAttributes; - /* an extended search */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's - we need to check we properly implement --SSS */ - /* either oid or type must be defined */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, ret, &oid); - asn1_end_tag(data); - } - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, ret, &attr); - asn1_end_tag(data); - } - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_read_LDAPString(data, ret, &value); - asn1_end_tag(data); - /* dnAttributes is marked as BOOLEAN DEFAULT FALSE - it is not marked as OPTIONAL but openldap tools - do not set this unless it is to be set as TRUE - NOTE: openldap tools do not work with AD as it - seems that AD always requires the dnAttributes - boolean value to be set */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_read_uint8(data, &dnAttributes); - asn1_end_tag(data); - } else { - dnAttributes = 0; - } - if ((oid == NULL && attr == NULL) || (value == NULL)) { - goto failed; - } - - if (oid) { - ret->operation = LDB_OP_EXTENDED; - - /* From the RFC2251: If the type field is - absent and matchingRule is present, the matchValue is compared - against all attributes in an entry which support that matchingRule - */ - if (attr) { - ret->u.extended.attr = talloc_steal(ret, attr); - } else { - ret->u.extended.attr = talloc_strdup(ret, "*"); - } - ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); - ret->u.extended.value.length = strlen(value); - ret->u.extended.dnAttributes = dnAttributes; - } else { - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attr); - ret->u.equality.value.data = talloc_steal(ret, value); - ret->u.equality.value.length = strlen(value); - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - - default: - DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -/* Decode a single LDAP attribute, possibly containing multiple values */ -static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element *attrib) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); - asn1_start_tag(data, ASN1_SET); - while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - DATA_BLOB blob; - asn1_read_OctetString(data, mem_ctx, &blob); - add_value_to_attrib(mem_ctx, &blob, attrib); - } - asn1_end_tag(data); - asn1_end_tag(data); - -} - -/* Decode a set of LDAP attributes, as found in the dereference control */ -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - struct ldb_message_element attrib; - ZERO_STRUCT(attrib); - ldap_decode_attrib(mem_ctx, data, &attrib); - add_attrib_to_array_talloc(mem_ctx, &attrib, - attributes, num_attributes); - } -} - -/* Decode a set of LDAP attributes, as found in a search entry */ -void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - ldap_decode_attribs_bare(mem_ctx, data, - attributes, num_attributes); - asn1_end_tag(data); -} - -/* This routine returns LDAP status codes */ - -_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) -{ - uint8_t tag; - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_Integer(data, &msg->messageid); - - if (!asn1_peek_uint8(data, &tag)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - - switch(tag) { - - case ASN1_APPLICATION(LDAP_TAG_BindRequest): { - struct ldap_BindRequest *r = &msg->r.BindRequest; - msg->type = LDAP_TAG_BindRequest; - asn1_start_tag(data, tag); - asn1_read_Integer(data, &r->version); - asn1_read_OctetString_talloc(msg, data, &r->dn); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { - int pwlen; - r->creds.password = ""; - r->mechanism = LDAP_AUTH_MECH_SIMPLE; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - pwlen = asn1_tag_remaining(data); - if (pwlen == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - if (pwlen != 0) { - char *pw = talloc_array(msg, char, pwlen+1); - if (!pw) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, pw, pwlen); - pw[pwlen] = '\0'; - r->creds.password = pw; - } - asn1_end_tag(data); - } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ - asn1_start_tag(data, ASN1_CONTEXT(3)); - r->mechanism = LDAP_AUTH_MECH_SASL; - asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, msg, &tmp_blob); - r->creds.SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->creds.SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->creds.SASL.secblob = NULL; - } - asn1_end_tag(data); - } else { - /* Neither Simple nor SASL bind */ - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_BindResponse): { - struct ldap_BindResponse *r = &msg->r.BindResponse; - msg->type = LDAP_TAG_BindResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->SASL.secblob = NULL; - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { - msg->type = LDAP_TAG_UnbindRequest; - asn1_start_tag(data, tag); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - msg->type = LDAP_TAG_SearchRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->basedn); - asn1_read_enumerated(data, (int *)&(r->scope)); - asn1_read_enumerated(data, (int *)&(r->deref)); - asn1_read_Integer(data, &r->sizelimit); - asn1_read_Integer(data, &r->timelimit); - asn1_read_BOOLEAN(data, &r->attributesonly); - - r->tree = ldap_decode_filter_tree(msg, data); - if (r->tree == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_attributes = 0; - r->attributes = NULL; - - while (asn1_tag_remaining(data) > 0) { - - const char *attr; - if (!asn1_read_OctetString_talloc(msg, data, - &attr)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - if (!add_string_to_array(msg, attr, - &r->attributes, - &r->num_attributes)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - msg->type = LDAP_TAG_SearchResultEntry; - r->attributes = NULL; - r->num_attributes = 0; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { - struct ldap_Result *r = &msg->r.SearchResultDone; - msg->type = LDAP_TAG_SearchResultDone; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - msg->type = LDAP_TAG_SearchResultReference; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->referral); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - msg->type = LDAP_TAG_ModifyRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_mods = 0; - r->mods = NULL; - - while (asn1_tag_remaining(data) > 0) { - struct ldap_mod mod; - int v; - ZERO_STRUCT(mod); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_enumerated(data, &v); - mod.type = v; - ldap_decode_attrib(msg, data, &mod.attrib); - asn1_end_tag(data); - if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { - struct ldap_Result *r = &msg->r.ModifyResponse; - msg->type = LDAP_TAG_ModifyResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddRequest): { - struct ldap_AddRequest *r = &msg->r.AddRequest; - msg->type = LDAP_TAG_AddRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - - r->attributes = NULL; - r->num_attributes = 0; - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddResponse): { - struct ldap_Result *r = &msg->r.AddResponse; - msg->type = LDAP_TAG_AddResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { - struct ldap_DelRequest *r = &msg->r.DelRequest; - int len; - char *dn; - msg->type = LDAP_TAG_DelRequest; - asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - dn = talloc_array(msg, char, len+1); - if (dn == NULL) - break; - asn1_read(data, dn, len); - dn[len] = '\0'; - r->dn = dn; - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_Result *r = &msg->r.DelResponse; - msg->type = LDAP_TAG_DelResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - msg->type = LDAP_TAG_ModifyDNRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_read_OctetString_talloc(msg, data, &r->newrdn); - asn1_read_BOOLEAN(data, &r->deleteolddn); - r->newsuperior = NULL; - if (asn1_tag_remaining(data) > 0) { - int len; - char *newsup; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - newsup = talloc_array(msg, char, len+1); - if (newsup == NULL) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, newsup, len); - newsup[len] = '\0'; - r->newsuperior = newsup; - asn1_end_tag(data); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - msg->type = LDAP_TAG_ModifyDNResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - msg->type = LDAP_TAG_CompareRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_CompareRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(msg, data, &r->attribute); - asn1_read_OctetString(data, msg, &r->value); - if (r->value.data) { - talloc_steal(msg, r->value.data); - } - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { - struct ldap_Result *r = &msg->r.CompareResponse; - msg->type = LDAP_TAG_CompareResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - msg->type = LDAP_TAG_AbandonRequest; - asn1_start_tag(data, tag); - asn1_read_implicit_Integer(data, &r->messageid); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedRequest; - asn1_start_tag(data,tag); - if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } else { - r->oid = NULL; - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - default: - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - msg->controls = NULL; - msg->controls_decoded = NULL; - - if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { - int i = 0; - struct ldb_control **ctrl = NULL; - bool *decoded = NULL; - - asn1_start_tag(data, ASN1_CONTEXT(0)); - - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - DATA_BLOB value; - /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ - - ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); - if (!ctrl) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - decoded = talloc_realloc(msg, decoded, bool, i+1); - if (!decoded) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - if (!ctrl[i]) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { - if (ctrl[i]->critical) { - ctrl[i]->data = NULL; - decoded[i] = false; - i++; - } else { - talloc_free(ctrl[i]); - ctrl[i] = NULL; - } - } else { - decoded[i] = true; - i++; - } - } - - if (ctrl != NULL) { - ctrl[i] = NULL; - } - - msg->controls = ctrl; - msg->controls_decoded = decoded; - - asn1_end_tag(data); - } - - asn1_end_tag(data); - if ((data->has_error) || (data->nesting != NULL)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - return NT_STATUS_OK; -} - - -/* - return NT_STATUS_OK if a blob has enough bytes in it to be a full - ldap packet. Set packet_size if true. -*/ -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) -{ - return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); -} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 3d99d6f47d..a642e671e6 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -21,200 +21,11 @@ #ifndef _SMB_LDAP_H_ #define _SMB_LDAP_H_ -#include "libcli/ldap/ldap_errors.h" -#include "lib/ldb/include/ldb.h" +#include "libcli/ldap/ldap_message.h" #include "librpc/gen_ndr/misc.h" -enum ldap_request_tag { - LDAP_TAG_BindRequest = 0, - LDAP_TAG_BindResponse = 1, - LDAP_TAG_UnbindRequest = 2, - LDAP_TAG_SearchRequest = 3, - LDAP_TAG_SearchResultEntry = 4, - LDAP_TAG_SearchResultDone = 5, - LDAP_TAG_ModifyRequest = 6, - LDAP_TAG_ModifyResponse = 7, - LDAP_TAG_AddRequest = 8, - LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, - LDAP_TAG_ModifyDNRequest = 12, - LDAP_TAG_ModifyDNResponse = 13, - LDAP_TAG_CompareRequest = 14, - LDAP_TAG_CompareResponse = 15, - LDAP_TAG_AbandonRequest = 16, - LDAP_TAG_SearchResultReference = 19, - LDAP_TAG_ExtendedRequest = 23, - LDAP_TAG_ExtendedResponse = 24 -}; - -enum ldap_auth_mechanism { - LDAP_AUTH_MECH_SIMPLE = 0, - LDAP_AUTH_MECH_SASL = 3 -}; - -struct ldap_Result { - int resultcode; - const char *dn; - const char *errormessage; - const char *referral; -}; - -struct ldap_BindRequest { - int version; - const char *dn; - enum ldap_auth_mechanism mechanism; - union { - const char *password; - struct { - const char *mechanism; - DATA_BLOB *secblob;/* optional */ - } SASL; - } creds; -}; - -struct ldap_BindResponse { - struct ldap_Result response; - union { - DATA_BLOB *secblob;/* optional */ - } SASL; -}; - -struct ldap_UnbindRequest { - uint8_t __dummy; -}; - -enum ldap_scope { - LDAP_SEARCH_SCOPE_BASE = 0, - LDAP_SEARCH_SCOPE_SINGLE = 1, - LDAP_SEARCH_SCOPE_SUB = 2 -}; - -enum ldap_deref { - LDAP_DEREFERENCE_NEVER = 0, - LDAP_DEREFERENCE_IN_SEARCHING = 1, - LDAP_DEREFERENCE_FINDING_BASE = 2, - LDAP_DEREFERENCE_ALWAYS -}; - -struct ldap_SearchRequest { - const char *basedn; - enum ldap_scope scope; - enum ldap_deref deref; - uint32_t timelimit; - uint32_t sizelimit; - bool attributesonly; - struct ldb_parse_tree *tree; - int num_attributes; - const char * const *attributes; -}; - -struct ldap_SearchResEntry { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_SearchResRef { - const char *referral; -}; - -enum ldap_modify_type { - LDAP_MODIFY_NONE = -1, - LDAP_MODIFY_ADD = 0, - LDAP_MODIFY_DELETE = 1, - LDAP_MODIFY_REPLACE = 2 -}; - -struct ldap_mod { - enum ldap_modify_type type; - struct ldb_message_element attrib; -}; - -struct ldap_ModifyRequest { - const char *dn; - int num_mods; - struct ldap_mod *mods; -}; - -struct ldap_AddRequest { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_DelRequest { - const char *dn; -}; - -struct ldap_ModifyDNRequest { - const char *dn; - const char *newrdn; - bool deleteolddn; - const char *newsuperior;/* optional */ -}; - -struct ldap_CompareRequest { - const char *dn; - const char *attribute; - DATA_BLOB value; -}; - -struct ldap_AbandonRequest { - uint32_t messageid; -}; - -struct ldap_ExtendedRequest { - const char *oid; - DATA_BLOB *value;/* optional */ -}; - -struct ldap_ExtendedResponse { - struct ldap_Result response; - const char *oid;/* optional */ - DATA_BLOB *value;/* optional */ -}; - -union ldap_Request { - struct ldap_Result GeneralResult; - struct ldap_BindRequest BindRequest; - struct ldap_BindResponse BindResponse; - struct ldap_UnbindRequest UnbindRequest; - struct ldap_SearchRequest SearchRequest; - struct ldap_SearchResEntry SearchResultEntry; - struct ldap_Result SearchResultDone; - struct ldap_SearchResRef SearchResultReference; - struct ldap_ModifyRequest ModifyRequest; - struct ldap_Result ModifyResponse; - struct ldap_AddRequest AddRequest; - struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; - struct ldap_ModifyDNRequest ModifyDNRequest; - struct ldap_Result ModifyDNResponse; - struct ldap_CompareRequest CompareRequest; - struct ldap_Result CompareResponse; - struct ldap_AbandonRequest AbandonRequest; - struct ldap_ExtendedRequest ExtendedRequest; - struct ldap_ExtendedResponse ExtendedResponse; -}; - - -struct ldap_message { - int messageid; - enum ldap_request_tag type; - union ldap_Request r; - struct ldb_control **controls; - bool *controls_decoded; -}; - struct tevent_context; struct cli_credentials; struct dom_sid; -struct asn1_data; - -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); #endif diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c new file mode 100644 index 0000000000..07362fa685 --- /dev/null +++ b/source4/libcli/ldap/ldap_message.c @@ -0,0 +1,1468 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#include "includes.h" +#include "../lib/util/asn1.h" +#include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_proto.h" + +_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct ldap_message); +} + + +static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldb_message_element *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); + if (attrib->values == NULL) + return false; + + attrib->values[attrib->num_values].data = talloc_steal(attrib->values, + value->data); + attrib->values[attrib->num_values].length = value->length; + attrib->num_values += 1; + return true; +} + +static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, + *attribs, + struct ldb_message_element, + *num_attribs+1); + + if (*attribs == NULL) + return false; + + (*attribs)[*num_attribs] = *attrib; + talloc_steal(*attribs, attrib->values); + talloc_steal(*attribs, attrib->name); + *num_attribs += 1; + return true; +} + +static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + + if (*mods == NULL) + return false; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return true; +} + +static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) +{ + int i; + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); + for (i=0; iu.list.num_elements; i++) { + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return false; + } + } + asn1_pop_tag(data); + break; + + case LDB_OP_NOT: + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.isnot.child)) { + return false; + } + asn1_pop_tag(data); + break; + + case LDB_OP_EQUALITY: + /* equality test */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, tree->u.equality.attr, + strlen(tree->u.equality.attr)); + asn1_write_OctetString(data, tree->u.equality.value.data, + tree->u.equality.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_SUBSTRING: + /* + SubstringFilter ::= SEQUENCE { + type AttributeDescription, + -- at least one must be present + substrings SEQUENCE OF CHOICE { + initial [0] LDAPString, + any [1] LDAPString, + final [2] LDAPString } } + */ + asn1_push_tag(data, ASN1_CONTEXT(4)); + asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + i = 0; + if ( ! tree->u.substring.start_with_wildcard) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + while (tree->u.substring.chunks[i]) { + int ctx; + + if (( ! tree->u.substring.chunks[i + 1]) && + (tree->u.substring.end_with_wildcard == 0)) { + ctx = 2; + } else { + ctx = 1; + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + case LDB_OP_GREATER: + /* greaterOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(5)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_LESS: + /* lessOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(6)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_PRESENT: + /* present test */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); + asn1_write_LDAPString(data, tree->u.present.attr); + asn1_pop_tag(data); + return !data->has_error; + + case LDB_OP_APPROX: + /* approx test */ + asn1_push_tag(data, ASN1_CONTEXT(8)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_EXTENDED: + /* + MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleID OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE + } + */ + asn1_push_tag(data, ASN1_CONTEXT(9)); + if (tree->u.extended.rule_id) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write_LDAPString(data, tree->u.extended.rule_id); + asn1_pop_tag(data); + } + if (tree->u.extended.attr) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_write_LDAPString(data, tree->u.extended.attr); + asn1_pop_tag(data); + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); + asn1_pop_tag(data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_write_uint8(data, tree->u.extended.dnAttributes); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + default: + return false; + } + return !data->has_error; +} + +static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) +{ + asn1_write_enumerated(data, result->resultcode); + asn1_write_OctetString(data, result->dn, + (result->dn) ? strlen(result->dn) : 0); + asn1_write_OctetString(data, result->errormessage, + (result->errormessage) ? + strlen(result->errormessage) : 0); + if (result->referral) { + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, result->referral, + strlen(result->referral)); + asn1_pop_tag(data); + } +} + +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +{ + struct asn1_data *data = asn1_init(mem_ctx); + int i, j; + + if (!data) return false; + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_Integer(data, msg->messageid); + + switch (msg->type) { + case LDAP_TAG_BindRequest: { + struct ldap_BindRequest *r = &msg->r.BindRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_Integer(data, r->version); + asn1_write_OctetString(data, r->dn, + (r->dn != NULL) ? strlen(r->dn) : 0); + + switch (r->mechanism) { + case LDAP_AUTH_MECH_SIMPLE: + /* context, primitive */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->creds.password, + strlen(r->creds.password)); + asn1_pop_tag(data); + break; + case LDAP_AUTH_MECH_SASL: + /* context, constructed */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, r->creds.SASL.mechanism, + strlen(r->creds.SASL.mechanism)); + if (r->creds.SASL.secblob) { + asn1_write_OctetString(data, r->creds.SASL.secblob->data, + r->creds.SASL.secblob->length); + } + asn1_pop_tag(data); + break; + default: + return false; + } + + asn1_pop_tag(data); + break; + } + case LDAP_TAG_BindResponse: { + struct ldap_BindResponse *r = &msg->r.BindResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->SASL.secblob) { + asn1_write_ContextSimple(data, 7, r->SASL.secblob); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_UnbindRequest: { +/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ + break; + } + case LDAP_TAG_SearchRequest: { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(data, r->scope); + asn1_write_enumerated(data, r->deref); + asn1_write_Integer(data, r->sizelimit); + asn1_write_Integer(data, r->timelimit); + asn1_write_BOOLEAN(data, r->attributesonly); + + if (!ldap_push_filter(data, r->tree)) { + return false; + } + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + asn1_write_OctetString(data, r->attributes[i], + strlen(r->attributes[i])); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultEntry: { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attr = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attr->name, + strlen(attr->name)); + asn1_push_tag(data, ASN1_SEQUENCE(1)); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attr->values[j].data, + attr->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultDone: { + struct ldap_Result *r = &msg->r.SearchResultDone; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyRequest: { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_mods; i++) { + struct ldb_message_element *attrib = &r->mods[i].attrib; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(data, r->mods[i].type); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + + } + asn1_pop_tag(data); + asn1_pop_tag(data); + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyResponse: { + struct ldap_Result *r = &msg->r.ModifyResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddRequest: { + struct ldap_AddRequest *r = &msg->r.AddRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attrib = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jattributes[i].num_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddResponse: { + struct ldap_Result *r = &msg->r.AddResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write(data, r->dn, strlen(r->dn)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNRequest: { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN(data, r->deleteolddn); + if (r->newsuperior) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->newsuperior, + strlen(r->newsuperior)); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareRequest: { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, r->attribute, + strlen(r->attribute)); + asn1_write_OctetString(data, r->value.data, + r->value.length); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AbandonRequest: { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write_implicit_Integer(data, r->messageid); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultReference: { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->referral, strlen(r->referral)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedRequest: { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedResponse: { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->oid) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + } + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + default: + return false; + } + + if (msg->controls != NULL) { + asn1_push_tag(data, ASN1_CONTEXT(0)); + + for (i = 0; msg->controls[i] != NULL; i++) { + if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { + return false; + } + } + + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + + if (data->has_error) { + asn1_free(data); + return false; + } + + *result = data_blob_talloc(mem_ctx, data->data, data->length); + asn1_free(data); + return true; +} + +static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, + DATA_BLOB blob) +{ + char *result = talloc_array(mem_ctx, char, blob.length+1); + memcpy(result, blob.data, blob.length); + result[blob.length] = '\0'; + return result; +} + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result) +{ + DATA_BLOB string; + if (!asn1_read_OctetString(data, mem_ctx, &string)) + return false; + *result = blob2string_talloc(mem_ctx, string); + data_blob_free(&string); + return true; +} + +static void ldap_decode_response(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + struct ldap_Result *result) +{ + asn1_read_enumerated(data, &result->resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); + asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); + asn1_end_tag(data); + } else { + result->referral = NULL; + } +} + +static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) +{ + + chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); + if (chunks == NULL) { + return NULL; + } + + chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); + if (chunks[chunk_num] == NULL) { + return NULL; + } + + chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); + if (chunks[chunk_num]->data == NULL) { + return NULL; + } + chunks[chunk_num]->length = strlen(value); + + chunks[chunk_num + 1] = '\0'; + + return chunks; +} + + +/* + parse the ASN.1 formatted search string into a ldb_parse_tree +*/ +static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, + struct asn1_data *data) +{ + uint8_t filter_tag; + struct ldb_parse_tree *ret; + + if (!asn1_peek_uint8(data, &filter_tag)) { + return NULL; + } + + filter_tag &= 0x1f; /* strip off the asn1 stuff */ + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (ret == NULL) return NULL; + + switch(filter_tag) { + case 0: + case 1: + /* AND or OR of one or more filters */ + ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; + ret->u.list.num_elements = 0; + ret->u.list.elements = NULL; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + while (asn1_tag_remaining(data) > 0) { + struct ldb_parse_tree *subtree; + subtree = ldap_decode_filter_tree(ret, data); + if (subtree == NULL) { + goto failed; + } + ret->u.list.elements = + talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); + if (ret->u.list.elements == NULL) { + goto failed; + } + talloc_steal(ret->u.list.elements, subtree); + ret->u.list.elements[ret->u.list.num_elements] = subtree; + ret->u.list.num_elements++; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 2: + /* 'not' operation */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + ret->operation = LDB_OP_NOT; + ret->u.isnot.child = ldap_decode_filter_tree(ret, data); + if (ret->u.isnot.child == NULL) { + goto failed; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 3: { + /* equalityMatch */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attrib); + ret->u.equality.value.data = talloc_steal(ret, value.data); + ret->u.equality.value.length = value.length; + break; + } + case 4: { + /* substrings */ + DATA_BLOB attr; + uint8_t subs_tag; + char *value; + int chunk_num = 0; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); + ret->u.substring.chunks = NULL; + ret->u.substring.start_with_wildcard = 1; + ret->u.substring.end_with_wildcard = 1; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + goto failed; + } + + while (asn1_tag_remaining(data)) { + asn1_peek_uint8(data, &subs_tag); + subs_tag &= 0x1f; /* strip off the asn1 stuff */ + if (subs_tag > 2) goto failed; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); + asn1_read_LDAPString(data, mem_ctx, &value); + asn1_end_tag(data); + + switch (subs_tag) { + case 0: + if (ret->u.substring.chunks != NULL) { + /* initial value found in the middle */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.start_with_wildcard = 0; + chunk_num = 1; + break; + + case 1: + if (ret->u.substring.end_with_wildcard == 0) { + /* "any" value found after a "final" value */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + chunk_num++; + break; + + case 2: + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.end_with_wildcard = 0; + break; + + default: + goto failed; + } + + } + + if (!asn1_end_tag(data)) { /* SEQUENCE */ + goto failed; + } + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 5: { + /* greaterOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 6: { + /* lessOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 7: { + /* Normal presence, "attribute=*" */ + char *attr; + + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { + goto failed; + } + if (!asn1_read_LDAPString(data, ret, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = talloc_steal(ret, attr); + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 8: { + /* approx */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 9: { + char *oid = NULL, *attr = NULL, *value; + uint8_t dnAttributes; + /* an extended search */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's + we need to check we properly implement --SSS */ + /* either oid or type must be defined */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, ret, &oid); + asn1_end_tag(data); + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, ret, &attr); + asn1_end_tag(data); + } + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_read_LDAPString(data, ret, &value); + asn1_end_tag(data); + /* dnAttributes is marked as BOOLEAN DEFAULT FALSE + it is not marked as OPTIONAL but openldap tools + do not set this unless it is to be set as TRUE + NOTE: openldap tools do not work with AD as it + seems that AD always requires the dnAttributes + boolean value to be set */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + } else { + dnAttributes = 0; + } + if ((oid == NULL && attr == NULL) || (value == NULL)) { + goto failed; + } + + if (oid) { + ret->operation = LDB_OP_EXTENDED; + + /* From the RFC2251: If the type field is + absent and matchingRule is present, the matchValue is compared + against all attributes in an entry which support that matchingRule + */ + if (attr) { + ret->u.extended.attr = talloc_steal(ret, attr); + } else { + ret->u.extended.attr = talloc_strdup(ret, "*"); + } + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + } else { + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attr); + ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.length = strlen(value); + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + + default: + DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); + goto failed; + } + + return ret; + +failed: + talloc_free(ret); + return NULL; +} + +/* Decode a single LDAP attribute, possibly containing multiple values */ +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element *attrib) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); + asn1_start_tag(data, ASN1_SET); + while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB blob; + asn1_read_OctetString(data, mem_ctx, &blob); + add_value_to_attrib(mem_ctx, &blob, attrib); + } + asn1_end_tag(data); + asn1_end_tag(data); + +} + +/* Decode a set of LDAP attributes, as found in the dereference control */ +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + struct ldb_message_element attrib; + ZERO_STRUCT(attrib); + ldap_decode_attrib(mem_ctx, data, &attrib); + add_attrib_to_array_talloc(mem_ctx, &attrib, + attributes, num_attributes); + } +} + +/* Decode a set of LDAP attributes, as found in a search entry */ +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + ldap_decode_attribs_bare(mem_ctx, data, + attributes, num_attributes); + asn1_end_tag(data); +} + +/* This routine returns LDAP status codes */ + +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +{ + uint8_t tag; + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_Integer(data, &msg->messageid); + + if (!asn1_peek_uint8(data, &tag)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + + switch(tag) { + + case ASN1_APPLICATION(LDAP_TAG_BindRequest): { + struct ldap_BindRequest *r = &msg->r.BindRequest; + msg->type = LDAP_TAG_BindRequest; + asn1_start_tag(data, tag); + asn1_read_Integer(data, &r->version); + asn1_read_OctetString_talloc(msg, data, &r->dn); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { + int pwlen; + r->creds.password = ""; + r->mechanism = LDAP_AUTH_MECH_SIMPLE; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + pwlen = asn1_tag_remaining(data); + if (pwlen == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + if (pwlen != 0) { + char *pw = talloc_array(msg, char, pwlen+1); + if (!pw) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, pw, pwlen); + pw[pwlen] = '\0'; + r->creds.password = pw; + } + asn1_end_tag(data); + } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ + asn1_start_tag(data, ASN1_CONTEXT(3)); + r->mechanism = LDAP_AUTH_MECH_SASL; + asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, msg, &tmp_blob); + r->creds.SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->creds.SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->creds.SASL.secblob = NULL; + } + asn1_end_tag(data); + } else { + /* Neither Simple nor SASL bind */ + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_BindResponse): { + struct ldap_BindResponse *r = &msg->r.BindResponse; + msg->type = LDAP_TAG_BindResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_ContextSimple(data, 7, &tmp_blob); + r->SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->SASL.secblob = NULL; + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { + msg->type = LDAP_TAG_UnbindRequest; + asn1_start_tag(data, tag); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + msg->type = LDAP_TAG_SearchRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->basedn); + asn1_read_enumerated(data, (int *)&(r->scope)); + asn1_read_enumerated(data, (int *)&(r->deref)); + asn1_read_Integer(data, &r->sizelimit); + asn1_read_Integer(data, &r->timelimit); + asn1_read_BOOLEAN(data, &r->attributesonly); + + r->tree = ldap_decode_filter_tree(msg, data); + if (r->tree == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_attributes = 0; + r->attributes = NULL; + + while (asn1_tag_remaining(data) > 0) { + + const char *attr; + if (!asn1_read_OctetString_talloc(msg, data, + &attr)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + if (!add_string_to_array(msg, attr, + &r->attributes, + &r->num_attributes)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + msg->type = LDAP_TAG_SearchResultEntry; + r->attributes = NULL; + r->num_attributes = 0; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { + struct ldap_Result *r = &msg->r.SearchResultDone; + msg->type = LDAP_TAG_SearchResultDone; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + msg->type = LDAP_TAG_SearchResultReference; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->referral); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + msg->type = LDAP_TAG_ModifyRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_mods = 0; + r->mods = NULL; + + while (asn1_tag_remaining(data) > 0) { + struct ldap_mod mod; + int v; + ZERO_STRUCT(mod); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_enumerated(data, &v); + mod.type = v; + ldap_decode_attrib(msg, data, &mod.attrib); + asn1_end_tag(data); + if (!add_mod_to_array_talloc(msg, &mod, + &r->mods, &r->num_mods)) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { + struct ldap_Result *r = &msg->r.ModifyResponse; + msg->type = LDAP_TAG_ModifyResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddRequest): { + struct ldap_AddRequest *r = &msg->r.AddRequest; + msg->type = LDAP_TAG_AddRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + + r->attributes = NULL; + r->num_attributes = 0; + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddResponse): { + struct ldap_Result *r = &msg->r.AddResponse; + msg->type = LDAP_TAG_AddResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; + int len; + char *dn; + msg->type = LDAP_TAG_DelRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + dn = talloc_array(msg, char, len+1); + if (dn == NULL) + break; + asn1_read(data, dn, len); + dn[len] = '\0'; + r->dn = dn; + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_Result *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + msg->type = LDAP_TAG_ModifyDNRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->newrdn); + asn1_read_BOOLEAN(data, &r->deleteolddn); + r->newsuperior = NULL; + if (asn1_tag_remaining(data) > 0) { + int len; + char *newsup; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + newsup = talloc_array(msg, char, len+1); + if (newsup == NULL) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, newsup, len); + newsup[len] = '\0'; + r->newsuperior = newsup; + asn1_end_tag(data); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + msg->type = LDAP_TAG_ModifyDNResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + msg->type = LDAP_TAG_CompareRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(msg, data, &r->attribute); + asn1_read_OctetString(data, msg, &r->value); + if (r->value.data) { + talloc_steal(msg, r->value.data); + } + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { + struct ldap_Result *r = &msg->r.CompareResponse; + msg->type = LDAP_TAG_CompareResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + msg->type = LDAP_TAG_AbandonRequest; + asn1_start_tag(data, tag); + asn1_read_implicit_Integer(data, &r->messageid); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedRequest; + asn1_start_tag(data,tag); + if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } else { + r->oid = NULL; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + default: + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + msg->controls = NULL; + msg->controls_decoded = NULL; + + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { + int i = 0; + struct ldb_control **ctrl = NULL; + bool *decoded = NULL; + + asn1_start_tag(data, ASN1_CONTEXT(0)); + + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + DATA_BLOB value; + /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ + + ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); + if (!ctrl) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + decoded = talloc_realloc(msg, decoded, bool, i+1); + if (!decoded) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + ctrl[i] = talloc(ctrl, struct ldb_control); + if (!ctrl[i]) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (ctrl[i]->critical) { + ctrl[i]->data = NULL; + decoded[i] = false; + i++; + } else { + talloc_free(ctrl[i]); + ctrl[i] = NULL; + } + } else { + decoded[i] = true; + i++; + } + } + + if (ctrl != NULL) { + ctrl[i] = NULL; + } + + msg->controls = ctrl; + msg->controls_decoded = decoded; + + asn1_end_tag(data); + } + + asn1_end_tag(data); + if ((data->has_error) || (data->nesting != NULL)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + return NT_STATUS_OK; +} + + +/* + return NT_STATUS_OK if a blob has enough bytes in it to be a full + ldap packet. Set packet_size if true. +*/ +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) +{ + return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); +} diff --git a/source4/libcli/ldap/ldap_message.h b/source4/libcli/ldap/ldap_message.h new file mode 100644 index 0000000000..47ee724e97 --- /dev/null +++ b/source4/libcli/ldap/ldap_message.h @@ -0,0 +1,225 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#ifndef _LIBCLI_LDAP_MESSAGE_H_ +#define _LIBCLI_LDAP_MESSAGE_H_ + +#include "libcli/ldap/ldap_errors.h" +#include "lib/ldb/include/ldb.h" + +enum ldap_request_tag { + LDAP_TAG_BindRequest = 0, + LDAP_TAG_BindResponse = 1, + LDAP_TAG_UnbindRequest = 2, + LDAP_TAG_SearchRequest = 3, + LDAP_TAG_SearchResultEntry = 4, + LDAP_TAG_SearchResultDone = 5, + LDAP_TAG_ModifyRequest = 6, + LDAP_TAG_ModifyResponse = 7, + LDAP_TAG_AddRequest = 8, + LDAP_TAG_AddResponse = 9, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, + LDAP_TAG_ModifyDNRequest = 12, + LDAP_TAG_ModifyDNResponse = 13, + LDAP_TAG_CompareRequest = 14, + LDAP_TAG_CompareResponse = 15, + LDAP_TAG_AbandonRequest = 16, + LDAP_TAG_SearchResultReference = 19, + LDAP_TAG_ExtendedRequest = 23, + LDAP_TAG_ExtendedResponse = 24 +}; + +enum ldap_auth_mechanism { + LDAP_AUTH_MECH_SIMPLE = 0, + LDAP_AUTH_MECH_SASL = 3 +}; + +struct ldap_Result { + int resultcode; + const char *dn; + const char *errormessage; + const char *referral; +}; + +struct ldap_BindRequest { + int version; + const char *dn; + enum ldap_auth_mechanism mechanism; + union { + const char *password; + struct { + const char *mechanism; + DATA_BLOB *secblob;/* optional */ + } SASL; + } creds; +}; + +struct ldap_BindResponse { + struct ldap_Result response; + union { + DATA_BLOB *secblob;/* optional */ + } SASL; +}; + +struct ldap_UnbindRequest { + uint8_t __dummy; +}; + +enum ldap_scope { + LDAP_SEARCH_SCOPE_BASE = 0, + LDAP_SEARCH_SCOPE_SINGLE = 1, + LDAP_SEARCH_SCOPE_SUB = 2 +}; + +enum ldap_deref { + LDAP_DEREFERENCE_NEVER = 0, + LDAP_DEREFERENCE_IN_SEARCHING = 1, + LDAP_DEREFERENCE_FINDING_BASE = 2, + LDAP_DEREFERENCE_ALWAYS +}; + +struct ldap_SearchRequest { + const char *basedn; + enum ldap_scope scope; + enum ldap_deref deref; + uint32_t timelimit; + uint32_t sizelimit; + bool attributesonly; + struct ldb_parse_tree *tree; + int num_attributes; + const char * const *attributes; +}; + +struct ldap_SearchResEntry { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_SearchResRef { + const char *referral; +}; + +enum ldap_modify_type { + LDAP_MODIFY_NONE = -1, + LDAP_MODIFY_ADD = 0, + LDAP_MODIFY_DELETE = 1, + LDAP_MODIFY_REPLACE = 2 +}; + +struct ldap_mod { + enum ldap_modify_type type; + struct ldb_message_element attrib; +}; + +struct ldap_ModifyRequest { + const char *dn; + int num_mods; + struct ldap_mod *mods; +}; + +struct ldap_AddRequest { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_DelRequest { + const char *dn; +}; + +struct ldap_ModifyDNRequest { + const char *dn; + const char *newrdn; + bool deleteolddn; + const char *newsuperior;/* optional */ +}; + +struct ldap_CompareRequest { + const char *dn; + const char *attribute; + DATA_BLOB value; +}; + +struct ldap_AbandonRequest { + uint32_t messageid; +}; + +struct ldap_ExtendedRequest { + const char *oid; + DATA_BLOB *value;/* optional */ +}; + +struct ldap_ExtendedResponse { + struct ldap_Result response; + const char *oid;/* optional */ + DATA_BLOB *value;/* optional */ +}; + +union ldap_Request { + struct ldap_Result GeneralResult; + struct ldap_BindRequest BindRequest; + struct ldap_BindResponse BindResponse; + struct ldap_UnbindRequest UnbindRequest; + struct ldap_SearchRequest SearchRequest; + struct ldap_SearchResEntry SearchResultEntry; + struct ldap_Result SearchResultDone; + struct ldap_SearchResRef SearchResultReference; + struct ldap_ModifyRequest ModifyRequest; + struct ldap_Result ModifyResponse; + struct ldap_AddRequest AddRequest; + struct ldap_Result AddResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; + struct ldap_ModifyDNRequest ModifyDNRequest; + struct ldap_Result ModifyDNResponse; + struct ldap_CompareRequest CompareRequest; + struct ldap_Result CompareResponse; + struct ldap_AbandonRequest AbandonRequest; + struct ldap_ExtendedRequest ExtendedRequest; + struct ldap_ExtendedResponse ExtendedResponse; +}; + + +struct ldap_message { + int messageid; + enum ldap_request_tag type; + union ldap_Request r; + struct ldb_control **controls; + bool *controls_decoded; +}; + +struct asn1_data; + +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result); + +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes); + +#endif diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c deleted file mode 100644 index e45213c004..0000000000 --- a/source4/libcli/ldap/ldap_msg.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Volker Lendecke 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - -#include "includes.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_client.h" -#include "libcli/ldap/ldap_proto.h" - - -_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldap_message); -} - - -bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, - attrib->values, - DATA_BLOB, - attrib->num_values+1); - if (attrib->values == NULL) - return false; - - attrib->values[attrib->num_values].data = talloc_steal(attrib->values, - value->data); - attrib->values[attrib->num_values].length = value->length; - attrib->num_values += 1; - return true; -} - -bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, - *attribs, - struct ldb_message_element, - *num_attribs+1); - - if (*attribs == NULL) - return false; - - (*attribs)[*num_attribs] = *attrib; - talloc_steal(*attribs, attrib->values); - talloc_steal(*attribs, attrib->name); - *num_attribs += 1; - return true; -} - -bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); - - if (*mods == NULL) - return false; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return true; -} - -- cgit From 1ab9c1a40290fbecf8b7090492363eab0443c7c6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:09:11 +0100 Subject: s4:libcli/ldap: remove reference to DEBUG() This prepares using ldap_message.c in source3/ later metze --- source4/libcli/ldap/ldap_message.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c index 07362fa685..d8bbf42634 100644 --- a/source4/libcli/ldap/ldap_message.c +++ b/source4/libcli/ldap/ldap_message.c @@ -940,7 +940,6 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } default: - DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); goto failed; } -- cgit From 536318549fba35a4d9eb60fbb2d0e91b88c44a7b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:13:41 +0100 Subject: libcli/ldap: move ldap_message.[ch] from source4/ to the toplevel metze --- libcli/ldap/config.mk | 7 + libcli/ldap/ldap_message.c | 1466 +++++++++++++++++++++++++++++++++++ libcli/ldap/ldap_message.h | 225 ++++++ source4/headermap.txt | 2 +- source4/libcli/ldap/config.mk | 8 - source4/libcli/ldap/ldap.h | 2 +- source4/libcli/ldap/ldap_message.c | 1467 ------------------------------------ source4/libcli/ldap/ldap_message.h | 225 ------ source4/main.mk | 2 + 9 files changed, 1702 insertions(+), 1702 deletions(-) create mode 100644 libcli/ldap/config.mk create mode 100644 libcli/ldap/ldap_message.c create mode 100644 libcli/ldap/ldap_message.h delete mode 100644 source4/libcli/ldap/ldap_message.c delete mode 100644 source4/libcli/ldap/ldap_message.h diff --git a/libcli/ldap/config.mk b/libcli/ldap/config.mk new file mode 100644 index 0000000000..067b6778b7 --- /dev/null +++ b/libcli/ldap/config.mk @@ -0,0 +1,7 @@ +[SUBSYSTEM::LIBCLI_LDAP_MESSAGE] +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB +PRIVATE_DEPENDENCIES = ASN1_UTIL + +LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix ../libcli/ldap/, \ + ldap_message.o) +PUBLIC_HEADERS += ../libcli/ldap/ldap_message.h diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c new file mode 100644 index 0000000000..e8ec716e64 --- /dev/null +++ b/libcli/ldap/ldap_message.c @@ -0,0 +1,1466 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#include "includes.h" +#include "../lib/util/asn1.h" +#include "../libcli/ldap/ldap_message.h" + +_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct ldap_message); +} + + +static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldb_message_element *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); + if (attrib->values == NULL) + return false; + + attrib->values[attrib->num_values].data = talloc_steal(attrib->values, + value->data); + attrib->values[attrib->num_values].length = value->length; + attrib->num_values += 1; + return true; +} + +static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, + *attribs, + struct ldb_message_element, + *num_attribs+1); + + if (*attribs == NULL) + return false; + + (*attribs)[*num_attribs] = *attrib; + talloc_steal(*attribs, attrib->values); + talloc_steal(*attribs, attrib->name); + *num_attribs += 1; + return true; +} + +static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + + if (*mods == NULL) + return false; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return true; +} + +static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) +{ + int i; + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); + for (i=0; iu.list.num_elements; i++) { + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return false; + } + } + asn1_pop_tag(data); + break; + + case LDB_OP_NOT: + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.isnot.child)) { + return false; + } + asn1_pop_tag(data); + break; + + case LDB_OP_EQUALITY: + /* equality test */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, tree->u.equality.attr, + strlen(tree->u.equality.attr)); + asn1_write_OctetString(data, tree->u.equality.value.data, + tree->u.equality.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_SUBSTRING: + /* + SubstringFilter ::= SEQUENCE { + type AttributeDescription, + -- at least one must be present + substrings SEQUENCE OF CHOICE { + initial [0] LDAPString, + any [1] LDAPString, + final [2] LDAPString } } + */ + asn1_push_tag(data, ASN1_CONTEXT(4)); + asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + i = 0; + if ( ! tree->u.substring.start_with_wildcard) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + while (tree->u.substring.chunks[i]) { + int ctx; + + if (( ! tree->u.substring.chunks[i + 1]) && + (tree->u.substring.end_with_wildcard == 0)) { + ctx = 2; + } else { + ctx = 1; + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + case LDB_OP_GREATER: + /* greaterOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(5)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_LESS: + /* lessOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(6)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_PRESENT: + /* present test */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); + asn1_write_LDAPString(data, tree->u.present.attr); + asn1_pop_tag(data); + return !data->has_error; + + case LDB_OP_APPROX: + /* approx test */ + asn1_push_tag(data, ASN1_CONTEXT(8)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_EXTENDED: + /* + MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleID OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE + } + */ + asn1_push_tag(data, ASN1_CONTEXT(9)); + if (tree->u.extended.rule_id) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write_LDAPString(data, tree->u.extended.rule_id); + asn1_pop_tag(data); + } + if (tree->u.extended.attr) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_write_LDAPString(data, tree->u.extended.attr); + asn1_pop_tag(data); + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); + asn1_pop_tag(data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_write_uint8(data, tree->u.extended.dnAttributes); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + default: + return false; + } + return !data->has_error; +} + +static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) +{ + asn1_write_enumerated(data, result->resultcode); + asn1_write_OctetString(data, result->dn, + (result->dn) ? strlen(result->dn) : 0); + asn1_write_OctetString(data, result->errormessage, + (result->errormessage) ? + strlen(result->errormessage) : 0); + if (result->referral) { + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, result->referral, + strlen(result->referral)); + asn1_pop_tag(data); + } +} + +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +{ + struct asn1_data *data = asn1_init(mem_ctx); + int i, j; + + if (!data) return false; + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_Integer(data, msg->messageid); + + switch (msg->type) { + case LDAP_TAG_BindRequest: { + struct ldap_BindRequest *r = &msg->r.BindRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_Integer(data, r->version); + asn1_write_OctetString(data, r->dn, + (r->dn != NULL) ? strlen(r->dn) : 0); + + switch (r->mechanism) { + case LDAP_AUTH_MECH_SIMPLE: + /* context, primitive */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->creds.password, + strlen(r->creds.password)); + asn1_pop_tag(data); + break; + case LDAP_AUTH_MECH_SASL: + /* context, constructed */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, r->creds.SASL.mechanism, + strlen(r->creds.SASL.mechanism)); + if (r->creds.SASL.secblob) { + asn1_write_OctetString(data, r->creds.SASL.secblob->data, + r->creds.SASL.secblob->length); + } + asn1_pop_tag(data); + break; + default: + return false; + } + + asn1_pop_tag(data); + break; + } + case LDAP_TAG_BindResponse: { + struct ldap_BindResponse *r = &msg->r.BindResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->SASL.secblob) { + asn1_write_ContextSimple(data, 7, r->SASL.secblob); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_UnbindRequest: { +/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ + break; + } + case LDAP_TAG_SearchRequest: { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(data, r->scope); + asn1_write_enumerated(data, r->deref); + asn1_write_Integer(data, r->sizelimit); + asn1_write_Integer(data, r->timelimit); + asn1_write_BOOLEAN(data, r->attributesonly); + + if (!ldap_push_filter(data, r->tree)) { + return false; + } + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + asn1_write_OctetString(data, r->attributes[i], + strlen(r->attributes[i])); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultEntry: { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attr = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attr->name, + strlen(attr->name)); + asn1_push_tag(data, ASN1_SEQUENCE(1)); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attr->values[j].data, + attr->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultDone: { + struct ldap_Result *r = &msg->r.SearchResultDone; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyRequest: { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_mods; i++) { + struct ldb_message_element *attrib = &r->mods[i].attrib; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(data, r->mods[i].type); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + + } + asn1_pop_tag(data); + asn1_pop_tag(data); + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyResponse: { + struct ldap_Result *r = &msg->r.ModifyResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddRequest: { + struct ldap_AddRequest *r = &msg->r.AddRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attrib = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jattributes[i].num_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddResponse: { + struct ldap_Result *r = &msg->r.AddResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write(data, r->dn, strlen(r->dn)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNRequest: { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN(data, r->deleteolddn); + if (r->newsuperior) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->newsuperior, + strlen(r->newsuperior)); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareRequest: { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, r->attribute, + strlen(r->attribute)); + asn1_write_OctetString(data, r->value.data, + r->value.length); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AbandonRequest: { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write_implicit_Integer(data, r->messageid); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultReference: { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->referral, strlen(r->referral)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedRequest: { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedResponse: { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->oid) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + } + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + default: + return false; + } + + if (msg->controls != NULL) { + asn1_push_tag(data, ASN1_CONTEXT(0)); + + for (i = 0; msg->controls[i] != NULL; i++) { + if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { + return false; + } + } + + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + + if (data->has_error) { + asn1_free(data); + return false; + } + + *result = data_blob_talloc(mem_ctx, data->data, data->length); + asn1_free(data); + return true; +} + +static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, + DATA_BLOB blob) +{ + char *result = talloc_array(mem_ctx, char, blob.length+1); + memcpy(result, blob.data, blob.length); + result[blob.length] = '\0'; + return result; +} + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result) +{ + DATA_BLOB string; + if (!asn1_read_OctetString(data, mem_ctx, &string)) + return false; + *result = blob2string_talloc(mem_ctx, string); + data_blob_free(&string); + return true; +} + +static void ldap_decode_response(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + struct ldap_Result *result) +{ + asn1_read_enumerated(data, &result->resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); + asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); + asn1_end_tag(data); + } else { + result->referral = NULL; + } +} + +static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) +{ + + chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); + if (chunks == NULL) { + return NULL; + } + + chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); + if (chunks[chunk_num] == NULL) { + return NULL; + } + + chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); + if (chunks[chunk_num]->data == NULL) { + return NULL; + } + chunks[chunk_num]->length = strlen(value); + + chunks[chunk_num + 1] = '\0'; + + return chunks; +} + + +/* + parse the ASN.1 formatted search string into a ldb_parse_tree +*/ +static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, + struct asn1_data *data) +{ + uint8_t filter_tag; + struct ldb_parse_tree *ret; + + if (!asn1_peek_uint8(data, &filter_tag)) { + return NULL; + } + + filter_tag &= 0x1f; /* strip off the asn1 stuff */ + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (ret == NULL) return NULL; + + switch(filter_tag) { + case 0: + case 1: + /* AND or OR of one or more filters */ + ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; + ret->u.list.num_elements = 0; + ret->u.list.elements = NULL; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + while (asn1_tag_remaining(data) > 0) { + struct ldb_parse_tree *subtree; + subtree = ldap_decode_filter_tree(ret, data); + if (subtree == NULL) { + goto failed; + } + ret->u.list.elements = + talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); + if (ret->u.list.elements == NULL) { + goto failed; + } + talloc_steal(ret->u.list.elements, subtree); + ret->u.list.elements[ret->u.list.num_elements] = subtree; + ret->u.list.num_elements++; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 2: + /* 'not' operation */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + ret->operation = LDB_OP_NOT; + ret->u.isnot.child = ldap_decode_filter_tree(ret, data); + if (ret->u.isnot.child == NULL) { + goto failed; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 3: { + /* equalityMatch */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attrib); + ret->u.equality.value.data = talloc_steal(ret, value.data); + ret->u.equality.value.length = value.length; + break; + } + case 4: { + /* substrings */ + DATA_BLOB attr; + uint8_t subs_tag; + char *value; + int chunk_num = 0; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); + ret->u.substring.chunks = NULL; + ret->u.substring.start_with_wildcard = 1; + ret->u.substring.end_with_wildcard = 1; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + goto failed; + } + + while (asn1_tag_remaining(data)) { + asn1_peek_uint8(data, &subs_tag); + subs_tag &= 0x1f; /* strip off the asn1 stuff */ + if (subs_tag > 2) goto failed; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); + asn1_read_LDAPString(data, mem_ctx, &value); + asn1_end_tag(data); + + switch (subs_tag) { + case 0: + if (ret->u.substring.chunks != NULL) { + /* initial value found in the middle */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.start_with_wildcard = 0; + chunk_num = 1; + break; + + case 1: + if (ret->u.substring.end_with_wildcard == 0) { + /* "any" value found after a "final" value */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + chunk_num++; + break; + + case 2: + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.end_with_wildcard = 0; + break; + + default: + goto failed; + } + + } + + if (!asn1_end_tag(data)) { /* SEQUENCE */ + goto failed; + } + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 5: { + /* greaterOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 6: { + /* lessOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 7: { + /* Normal presence, "attribute=*" */ + char *attr; + + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { + goto failed; + } + if (!asn1_read_LDAPString(data, ret, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = talloc_steal(ret, attr); + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 8: { + /* approx */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 9: { + char *oid = NULL, *attr = NULL, *value; + uint8_t dnAttributes; + /* an extended search */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's + we need to check we properly implement --SSS */ + /* either oid or type must be defined */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, ret, &oid); + asn1_end_tag(data); + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, ret, &attr); + asn1_end_tag(data); + } + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_read_LDAPString(data, ret, &value); + asn1_end_tag(data); + /* dnAttributes is marked as BOOLEAN DEFAULT FALSE + it is not marked as OPTIONAL but openldap tools + do not set this unless it is to be set as TRUE + NOTE: openldap tools do not work with AD as it + seems that AD always requires the dnAttributes + boolean value to be set */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + } else { + dnAttributes = 0; + } + if ((oid == NULL && attr == NULL) || (value == NULL)) { + goto failed; + } + + if (oid) { + ret->operation = LDB_OP_EXTENDED; + + /* From the RFC2251: If the type field is + absent and matchingRule is present, the matchValue is compared + against all attributes in an entry which support that matchingRule + */ + if (attr) { + ret->u.extended.attr = talloc_steal(ret, attr); + } else { + ret->u.extended.attr = talloc_strdup(ret, "*"); + } + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + } else { + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attr); + ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.length = strlen(value); + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + + default: + goto failed; + } + + return ret; + +failed: + talloc_free(ret); + return NULL; +} + +/* Decode a single LDAP attribute, possibly containing multiple values */ +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element *attrib) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); + asn1_start_tag(data, ASN1_SET); + while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB blob; + asn1_read_OctetString(data, mem_ctx, &blob); + add_value_to_attrib(mem_ctx, &blob, attrib); + } + asn1_end_tag(data); + asn1_end_tag(data); + +} + +/* Decode a set of LDAP attributes, as found in the dereference control */ +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + struct ldb_message_element attrib; + ZERO_STRUCT(attrib); + ldap_decode_attrib(mem_ctx, data, &attrib); + add_attrib_to_array_talloc(mem_ctx, &attrib, + attributes, num_attributes); + } +} + +/* Decode a set of LDAP attributes, as found in a search entry */ +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + ldap_decode_attribs_bare(mem_ctx, data, + attributes, num_attributes); + asn1_end_tag(data); +} + +/* This routine returns LDAP status codes */ + +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +{ + uint8_t tag; + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_Integer(data, &msg->messageid); + + if (!asn1_peek_uint8(data, &tag)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + + switch(tag) { + + case ASN1_APPLICATION(LDAP_TAG_BindRequest): { + struct ldap_BindRequest *r = &msg->r.BindRequest; + msg->type = LDAP_TAG_BindRequest; + asn1_start_tag(data, tag); + asn1_read_Integer(data, &r->version); + asn1_read_OctetString_talloc(msg, data, &r->dn); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { + int pwlen; + r->creds.password = ""; + r->mechanism = LDAP_AUTH_MECH_SIMPLE; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + pwlen = asn1_tag_remaining(data); + if (pwlen == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + if (pwlen != 0) { + char *pw = talloc_array(msg, char, pwlen+1); + if (!pw) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, pw, pwlen); + pw[pwlen] = '\0'; + r->creds.password = pw; + } + asn1_end_tag(data); + } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ + asn1_start_tag(data, ASN1_CONTEXT(3)); + r->mechanism = LDAP_AUTH_MECH_SASL; + asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, msg, &tmp_blob); + r->creds.SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->creds.SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->creds.SASL.secblob = NULL; + } + asn1_end_tag(data); + } else { + /* Neither Simple nor SASL bind */ + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_BindResponse): { + struct ldap_BindResponse *r = &msg->r.BindResponse; + msg->type = LDAP_TAG_BindResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_ContextSimple(data, 7, &tmp_blob); + r->SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->SASL.secblob = NULL; + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { + msg->type = LDAP_TAG_UnbindRequest; + asn1_start_tag(data, tag); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + msg->type = LDAP_TAG_SearchRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->basedn); + asn1_read_enumerated(data, (int *)&(r->scope)); + asn1_read_enumerated(data, (int *)&(r->deref)); + asn1_read_Integer(data, &r->sizelimit); + asn1_read_Integer(data, &r->timelimit); + asn1_read_BOOLEAN(data, &r->attributesonly); + + r->tree = ldap_decode_filter_tree(msg, data); + if (r->tree == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_attributes = 0; + r->attributes = NULL; + + while (asn1_tag_remaining(data) > 0) { + + const char *attr; + if (!asn1_read_OctetString_talloc(msg, data, + &attr)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + if (!add_string_to_array(msg, attr, + &r->attributes, + &r->num_attributes)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + msg->type = LDAP_TAG_SearchResultEntry; + r->attributes = NULL; + r->num_attributes = 0; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { + struct ldap_Result *r = &msg->r.SearchResultDone; + msg->type = LDAP_TAG_SearchResultDone; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + msg->type = LDAP_TAG_SearchResultReference; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->referral); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + msg->type = LDAP_TAG_ModifyRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_mods = 0; + r->mods = NULL; + + while (asn1_tag_remaining(data) > 0) { + struct ldap_mod mod; + int v; + ZERO_STRUCT(mod); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_enumerated(data, &v); + mod.type = v; + ldap_decode_attrib(msg, data, &mod.attrib); + asn1_end_tag(data); + if (!add_mod_to_array_talloc(msg, &mod, + &r->mods, &r->num_mods)) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { + struct ldap_Result *r = &msg->r.ModifyResponse; + msg->type = LDAP_TAG_ModifyResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddRequest): { + struct ldap_AddRequest *r = &msg->r.AddRequest; + msg->type = LDAP_TAG_AddRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + + r->attributes = NULL; + r->num_attributes = 0; + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddResponse): { + struct ldap_Result *r = &msg->r.AddResponse; + msg->type = LDAP_TAG_AddResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; + int len; + char *dn; + msg->type = LDAP_TAG_DelRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + dn = talloc_array(msg, char, len+1); + if (dn == NULL) + break; + asn1_read(data, dn, len); + dn[len] = '\0'; + r->dn = dn; + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_Result *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + msg->type = LDAP_TAG_ModifyDNRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->newrdn); + asn1_read_BOOLEAN(data, &r->deleteolddn); + r->newsuperior = NULL; + if (asn1_tag_remaining(data) > 0) { + int len; + char *newsup; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + newsup = talloc_array(msg, char, len+1); + if (newsup == NULL) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, newsup, len); + newsup[len] = '\0'; + r->newsuperior = newsup; + asn1_end_tag(data); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + msg->type = LDAP_TAG_ModifyDNResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + msg->type = LDAP_TAG_CompareRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(msg, data, &r->attribute); + asn1_read_OctetString(data, msg, &r->value); + if (r->value.data) { + talloc_steal(msg, r->value.data); + } + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { + struct ldap_Result *r = &msg->r.CompareResponse; + msg->type = LDAP_TAG_CompareResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + msg->type = LDAP_TAG_AbandonRequest; + asn1_start_tag(data, tag); + asn1_read_implicit_Integer(data, &r->messageid); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedRequest; + asn1_start_tag(data,tag); + if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } else { + r->oid = NULL; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + default: + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + msg->controls = NULL; + msg->controls_decoded = NULL; + + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { + int i = 0; + struct ldb_control **ctrl = NULL; + bool *decoded = NULL; + + asn1_start_tag(data, ASN1_CONTEXT(0)); + + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + DATA_BLOB value; + /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ + + ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); + if (!ctrl) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + decoded = talloc_realloc(msg, decoded, bool, i+1); + if (!decoded) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + ctrl[i] = talloc(ctrl, struct ldb_control); + if (!ctrl[i]) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (ctrl[i]->critical) { + ctrl[i]->data = NULL; + decoded[i] = false; + i++; + } else { + talloc_free(ctrl[i]); + ctrl[i] = NULL; + } + } else { + decoded[i] = true; + i++; + } + } + + if (ctrl != NULL) { + ctrl[i] = NULL; + } + + msg->controls = ctrl; + msg->controls_decoded = decoded; + + asn1_end_tag(data); + } + + asn1_end_tag(data); + if ((data->has_error) || (data->nesting != NULL)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + return NT_STATUS_OK; +} + + +/* + return NT_STATUS_OK if a blob has enough bytes in it to be a full + ldap packet. Set packet_size if true. +*/ +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) +{ + return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); +} diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h new file mode 100644 index 0000000000..47ee724e97 --- /dev/null +++ b/libcli/ldap/ldap_message.h @@ -0,0 +1,225 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#ifndef _LIBCLI_LDAP_MESSAGE_H_ +#define _LIBCLI_LDAP_MESSAGE_H_ + +#include "libcli/ldap/ldap_errors.h" +#include "lib/ldb/include/ldb.h" + +enum ldap_request_tag { + LDAP_TAG_BindRequest = 0, + LDAP_TAG_BindResponse = 1, + LDAP_TAG_UnbindRequest = 2, + LDAP_TAG_SearchRequest = 3, + LDAP_TAG_SearchResultEntry = 4, + LDAP_TAG_SearchResultDone = 5, + LDAP_TAG_ModifyRequest = 6, + LDAP_TAG_ModifyResponse = 7, + LDAP_TAG_AddRequest = 8, + LDAP_TAG_AddResponse = 9, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, + LDAP_TAG_ModifyDNRequest = 12, + LDAP_TAG_ModifyDNResponse = 13, + LDAP_TAG_CompareRequest = 14, + LDAP_TAG_CompareResponse = 15, + LDAP_TAG_AbandonRequest = 16, + LDAP_TAG_SearchResultReference = 19, + LDAP_TAG_ExtendedRequest = 23, + LDAP_TAG_ExtendedResponse = 24 +}; + +enum ldap_auth_mechanism { + LDAP_AUTH_MECH_SIMPLE = 0, + LDAP_AUTH_MECH_SASL = 3 +}; + +struct ldap_Result { + int resultcode; + const char *dn; + const char *errormessage; + const char *referral; +}; + +struct ldap_BindRequest { + int version; + const char *dn; + enum ldap_auth_mechanism mechanism; + union { + const char *password; + struct { + const char *mechanism; + DATA_BLOB *secblob;/* optional */ + } SASL; + } creds; +}; + +struct ldap_BindResponse { + struct ldap_Result response; + union { + DATA_BLOB *secblob;/* optional */ + } SASL; +}; + +struct ldap_UnbindRequest { + uint8_t __dummy; +}; + +enum ldap_scope { + LDAP_SEARCH_SCOPE_BASE = 0, + LDAP_SEARCH_SCOPE_SINGLE = 1, + LDAP_SEARCH_SCOPE_SUB = 2 +}; + +enum ldap_deref { + LDAP_DEREFERENCE_NEVER = 0, + LDAP_DEREFERENCE_IN_SEARCHING = 1, + LDAP_DEREFERENCE_FINDING_BASE = 2, + LDAP_DEREFERENCE_ALWAYS +}; + +struct ldap_SearchRequest { + const char *basedn; + enum ldap_scope scope; + enum ldap_deref deref; + uint32_t timelimit; + uint32_t sizelimit; + bool attributesonly; + struct ldb_parse_tree *tree; + int num_attributes; + const char * const *attributes; +}; + +struct ldap_SearchResEntry { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_SearchResRef { + const char *referral; +}; + +enum ldap_modify_type { + LDAP_MODIFY_NONE = -1, + LDAP_MODIFY_ADD = 0, + LDAP_MODIFY_DELETE = 1, + LDAP_MODIFY_REPLACE = 2 +}; + +struct ldap_mod { + enum ldap_modify_type type; + struct ldb_message_element attrib; +}; + +struct ldap_ModifyRequest { + const char *dn; + int num_mods; + struct ldap_mod *mods; +}; + +struct ldap_AddRequest { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_DelRequest { + const char *dn; +}; + +struct ldap_ModifyDNRequest { + const char *dn; + const char *newrdn; + bool deleteolddn; + const char *newsuperior;/* optional */ +}; + +struct ldap_CompareRequest { + const char *dn; + const char *attribute; + DATA_BLOB value; +}; + +struct ldap_AbandonRequest { + uint32_t messageid; +}; + +struct ldap_ExtendedRequest { + const char *oid; + DATA_BLOB *value;/* optional */ +}; + +struct ldap_ExtendedResponse { + struct ldap_Result response; + const char *oid;/* optional */ + DATA_BLOB *value;/* optional */ +}; + +union ldap_Request { + struct ldap_Result GeneralResult; + struct ldap_BindRequest BindRequest; + struct ldap_BindResponse BindResponse; + struct ldap_UnbindRequest UnbindRequest; + struct ldap_SearchRequest SearchRequest; + struct ldap_SearchResEntry SearchResultEntry; + struct ldap_Result SearchResultDone; + struct ldap_SearchResRef SearchResultReference; + struct ldap_ModifyRequest ModifyRequest; + struct ldap_Result ModifyResponse; + struct ldap_AddRequest AddRequest; + struct ldap_Result AddResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; + struct ldap_ModifyDNRequest ModifyDNRequest; + struct ldap_Result ModifyDNResponse; + struct ldap_CompareRequest CompareRequest; + struct ldap_Result CompareResponse; + struct ldap_AbandonRequest AbandonRequest; + struct ldap_ExtendedRequest ExtendedRequest; + struct ldap_ExtendedResponse ExtendedResponse; +}; + + +struct ldap_message { + int messageid; + enum ldap_request_tag type; + union ldap_Request r; + struct ldb_control **controls; + bool *controls_decoded; +}; + +struct asn1_data; + +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result); + +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes); + +#endif diff --git a/source4/headermap.txt b/source4/headermap.txt index 8a968315bf..9d8e698f5c 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -49,7 +49,7 @@ param/share.h: share.h ../lib/util/util_tdb.h: util_tdb.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h -libcli/ldap/ldap_message.h: ldap_message.h +../libcli/ldap/ldap_message.h: ldap_message.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index a0e178ac40..a1f34a6513 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,11 +1,3 @@ -[SUBSYSTEM::LIBCLI_LDAP_MESSAGE] -PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB -PRIVATE_DEPENDENCIES = ASN1_UTIL - -LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ - ldap_message.o) -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_message.h - [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index a642e671e6..79cfef2128 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -21,7 +21,7 @@ #ifndef _SMB_LDAP_H_ #define _SMB_LDAP_H_ -#include "libcli/ldap/ldap_message.h" +#include "../libcli/ldap/ldap_message.h" #include "librpc/gen_ndr/misc.h" struct tevent_context; diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c deleted file mode 100644 index d8bbf42634..0000000000 --- a/source4/libcli/ldap/ldap_message.c +++ /dev/null @@ -1,1467 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - -#include "includes.h" -#include "../lib/util/asn1.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_proto.h" - -_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldap_message); -} - - -static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, - attrib->values, - DATA_BLOB, - attrib->num_values+1); - if (attrib->values == NULL) - return false; - - attrib->values[attrib->num_values].data = talloc_steal(attrib->values, - value->data); - attrib->values[attrib->num_values].length = value->length; - attrib->num_values += 1; - return true; -} - -static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, - *attribs, - struct ldb_message_element, - *num_attribs+1); - - if (*attribs == NULL) - return false; - - (*attribs)[*num_attribs] = *attrib; - talloc_steal(*attribs, attrib->values); - talloc_steal(*attribs, attrib->name); - *num_attribs += 1; - return true; -} - -static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); - - if (*mods == NULL) - return false; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return true; -} - -static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) -{ - int i; - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); - for (i=0; iu.list.num_elements; i++) { - if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return false; - } - } - asn1_pop_tag(data); - break; - - case LDB_OP_NOT: - asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.isnot.child)) { - return false; - } - asn1_pop_tag(data); - break; - - case LDB_OP_EQUALITY: - /* equality test */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, tree->u.equality.attr, - strlen(tree->u.equality.attr)); - asn1_write_OctetString(data, tree->u.equality.value.data, - tree->u.equality.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_SUBSTRING: - /* - SubstringFilter ::= SEQUENCE { - type AttributeDescription, - -- at least one must be present - substrings SEQUENCE OF CHOICE { - initial [0] LDAPString, - any [1] LDAPString, - final [2] LDAPString } } - */ - asn1_push_tag(data, ASN1_CONTEXT(4)); - asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - i = 0; - if ( ! tree->u.substring.start_with_wildcard) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - while (tree->u.substring.chunks[i]) { - int ctx; - - if (( ! tree->u.substring.chunks[i + 1]) && - (tree->u.substring.end_with_wildcard == 0)) { - ctx = 2; - } else { - ctx = 1; - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - case LDB_OP_GREATER: - /* greaterOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(5)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_LESS: - /* lessOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(6)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_PRESENT: - /* present test */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); - asn1_write_LDAPString(data, tree->u.present.attr); - asn1_pop_tag(data); - return !data->has_error; - - case LDB_OP_APPROX: - /* approx test */ - asn1_push_tag(data, ASN1_CONTEXT(8)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_EXTENDED: - /* - MatchingRuleAssertion ::= SEQUENCE { - matchingRule [1] MatchingRuleID OPTIONAL, - type [2] AttributeDescription OPTIONAL, - matchValue [3] AssertionValue, - dnAttributes [4] BOOLEAN DEFAULT FALSE - } - */ - asn1_push_tag(data, ASN1_CONTEXT(9)); - if (tree->u.extended.rule_id) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write_LDAPString(data, tree->u.extended.rule_id); - asn1_pop_tag(data); - } - if (tree->u.extended.attr) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_write_LDAPString(data, tree->u.extended.attr); - asn1_pop_tag(data); - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); - asn1_pop_tag(data); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_write_uint8(data, tree->u.extended.dnAttributes); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - default: - return false; - } - return !data->has_error; -} - -static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) -{ - asn1_write_enumerated(data, result->resultcode); - asn1_write_OctetString(data, result->dn, - (result->dn) ? strlen(result->dn) : 0); - asn1_write_OctetString(data, result->errormessage, - (result->errormessage) ? - strlen(result->errormessage) : 0); - if (result->referral) { - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, result->referral, - strlen(result->referral)); - asn1_pop_tag(data); - } -} - -_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) -{ - struct asn1_data *data = asn1_init(mem_ctx); - int i, j; - - if (!data) return false; - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_Integer(data, msg->messageid); - - switch (msg->type) { - case LDAP_TAG_BindRequest: { - struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_Integer(data, r->version); - asn1_write_OctetString(data, r->dn, - (r->dn != NULL) ? strlen(r->dn) : 0); - - switch (r->mechanism) { - case LDAP_AUTH_MECH_SIMPLE: - /* context, primitive */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->creds.password, - strlen(r->creds.password)); - asn1_pop_tag(data); - break; - case LDAP_AUTH_MECH_SASL: - /* context, constructed */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, r->creds.SASL.mechanism, - strlen(r->creds.SASL.mechanism)); - if (r->creds.SASL.secblob) { - asn1_write_OctetString(data, r->creds.SASL.secblob->data, - r->creds.SASL.secblob->length); - } - asn1_pop_tag(data); - break; - default: - return false; - } - - asn1_pop_tag(data); - break; - } - case LDAP_TAG_BindResponse: { - struct ldap_BindResponse *r = &msg->r.BindResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->SASL.secblob) { - asn1_write_ContextSimple(data, 7, r->SASL.secblob); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_UnbindRequest: { -/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ - break; - } - case LDAP_TAG_SearchRequest: { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); - asn1_write_enumerated(data, r->scope); - asn1_write_enumerated(data, r->deref); - asn1_write_Integer(data, r->sizelimit); - asn1_write_Integer(data, r->timelimit); - asn1_write_BOOLEAN(data, r->attributesonly); - - if (!ldap_push_filter(data, r->tree)) { - return false; - } - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - asn1_write_OctetString(data, r->attributes[i], - strlen(r->attributes[i])); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultEntry: { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attr = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attr->name, - strlen(attr->name)); - asn1_push_tag(data, ASN1_SEQUENCE(1)); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attr->values[j].data, - attr->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultDone: { - struct ldap_Result *r = &msg->r.SearchResultDone; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyRequest: { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_mods; i++) { - struct ldb_message_element *attrib = &r->mods[i].attrib; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_enumerated(data, r->mods[i].type); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - - } - asn1_pop_tag(data); - asn1_pop_tag(data); - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyResponse: { - struct ldap_Result *r = &msg->r.ModifyResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddRequest: { - struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attrib = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jattributes[i].num_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddResponse: { - struct ldap_Result *r = &msg->r.AddResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelRequest: { - struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write(data, r->dn, strlen(r->dn)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelResponse: { - struct ldap_Result *r = &msg->r.DelResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNRequest: { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN(data, r->deleteolddn); - if (r->newsuperior) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->newsuperior, - strlen(r->newsuperior)); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareRequest: { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, r->attribute, - strlen(r->attribute)); - asn1_write_OctetString(data, r->value.data, - r->value.length); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AbandonRequest: { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write_implicit_Integer(data, r->messageid); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultReference: { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->referral, strlen(r->referral)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedRequest: { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedResponse: { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->oid) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - } - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - default: - return false; - } - - if (msg->controls != NULL) { - asn1_push_tag(data, ASN1_CONTEXT(0)); - - for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { - return false; - } - } - - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - - if (data->has_error) { - asn1_free(data); - return false; - } - - *result = data_blob_talloc(mem_ctx, data->data, data->length); - asn1_free(data); - return true; -} - -static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, - DATA_BLOB blob) -{ - char *result = talloc_array(mem_ctx, char, blob.length+1); - memcpy(result, blob.data, blob.length); - result[blob.length] = '\0'; - return result; -} - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result) -{ - DATA_BLOB string; - if (!asn1_read_OctetString(data, mem_ctx, &string)) - return false; - *result = blob2string_talloc(mem_ctx, string); - data_blob_free(&string); - return true; -} - -static void ldap_decode_response(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - struct ldap_Result *result) -{ - asn1_read_enumerated(data, &result->resultcode); - asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); - asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { - asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); - asn1_end_tag(data); - } else { - result->referral = NULL; - } -} - -static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) -{ - - chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); - if (chunks == NULL) { - return NULL; - } - - chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); - if (chunks[chunk_num] == NULL) { - return NULL; - } - - chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); - if (chunks[chunk_num]->data == NULL) { - return NULL; - } - chunks[chunk_num]->length = strlen(value); - - chunks[chunk_num + 1] = '\0'; - - return chunks; -} - - -/* - parse the ASN.1 formatted search string into a ldb_parse_tree -*/ -static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, - struct asn1_data *data) -{ - uint8_t filter_tag; - struct ldb_parse_tree *ret; - - if (!asn1_peek_uint8(data, &filter_tag)) { - return NULL; - } - - filter_tag &= 0x1f; /* strip off the asn1 stuff */ - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (ret == NULL) return NULL; - - switch(filter_tag) { - case 0: - case 1: - /* AND or OR of one or more filters */ - ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; - ret->u.list.num_elements = 0; - ret->u.list.elements = NULL; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - while (asn1_tag_remaining(data) > 0) { - struct ldb_parse_tree *subtree; - subtree = ldap_decode_filter_tree(ret, data); - if (subtree == NULL) { - goto failed; - } - ret->u.list.elements = - talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements+1); - if (ret->u.list.elements == NULL) { - goto failed; - } - talloc_steal(ret->u.list.elements, subtree); - ret->u.list.elements[ret->u.list.num_elements] = subtree; - ret->u.list.num_elements++; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 2: - /* 'not' operation */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldap_decode_filter_tree(ret, data); - if (ret->u.isnot.child == NULL) { - goto failed; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 3: { - /* equalityMatch */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attrib); - ret->u.equality.value.data = talloc_steal(ret, value.data); - ret->u.equality.value.length = value.length; - break; - } - case 4: { - /* substrings */ - DATA_BLOB attr; - uint8_t subs_tag; - char *value; - int chunk_num = 0; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); - ret->u.substring.chunks = NULL; - ret->u.substring.start_with_wildcard = 1; - ret->u.substring.end_with_wildcard = 1; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - goto failed; - } - - while (asn1_tag_remaining(data)) { - asn1_peek_uint8(data, &subs_tag); - subs_tag &= 0x1f; /* strip off the asn1 stuff */ - if (subs_tag > 2) goto failed; - - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); - asn1_read_LDAPString(data, mem_ctx, &value); - asn1_end_tag(data); - - switch (subs_tag) { - case 0: - if (ret->u.substring.chunks != NULL) { - /* initial value found in the middle */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.start_with_wildcard = 0; - chunk_num = 1; - break; - - case 1: - if (ret->u.substring.end_with_wildcard == 0) { - /* "any" value found after a "final" value */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - chunk_num++; - break; - - case 2: - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.end_with_wildcard = 0; - break; - - default: - goto failed; - } - - } - - if (!asn1_end_tag(data)) { /* SEQUENCE */ - goto failed; - } - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 5: { - /* greaterOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 6: { - /* lessOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 7: { - /* Normal presence, "attribute=*" */ - char *attr; - - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { - goto failed; - } - if (!asn1_read_LDAPString(data, ret, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = talloc_steal(ret, attr); - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 8: { - /* approx */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 9: { - char *oid = NULL, *attr = NULL, *value; - uint8_t dnAttributes; - /* an extended search */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's - we need to check we properly implement --SSS */ - /* either oid or type must be defined */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, ret, &oid); - asn1_end_tag(data); - } - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, ret, &attr); - asn1_end_tag(data); - } - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_read_LDAPString(data, ret, &value); - asn1_end_tag(data); - /* dnAttributes is marked as BOOLEAN DEFAULT FALSE - it is not marked as OPTIONAL but openldap tools - do not set this unless it is to be set as TRUE - NOTE: openldap tools do not work with AD as it - seems that AD always requires the dnAttributes - boolean value to be set */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_read_uint8(data, &dnAttributes); - asn1_end_tag(data); - } else { - dnAttributes = 0; - } - if ((oid == NULL && attr == NULL) || (value == NULL)) { - goto failed; - } - - if (oid) { - ret->operation = LDB_OP_EXTENDED; - - /* From the RFC2251: If the type field is - absent and matchingRule is present, the matchValue is compared - against all attributes in an entry which support that matchingRule - */ - if (attr) { - ret->u.extended.attr = talloc_steal(ret, attr); - } else { - ret->u.extended.attr = talloc_strdup(ret, "*"); - } - ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); - ret->u.extended.value.length = strlen(value); - ret->u.extended.dnAttributes = dnAttributes; - } else { - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attr); - ret->u.equality.value.data = talloc_steal(ret, value); - ret->u.equality.value.length = strlen(value); - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - - default: - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -/* Decode a single LDAP attribute, possibly containing multiple values */ -static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element *attrib) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); - asn1_start_tag(data, ASN1_SET); - while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - DATA_BLOB blob; - asn1_read_OctetString(data, mem_ctx, &blob); - add_value_to_attrib(mem_ctx, &blob, attrib); - } - asn1_end_tag(data); - asn1_end_tag(data); - -} - -/* Decode a set of LDAP attributes, as found in the dereference control */ -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - struct ldb_message_element attrib; - ZERO_STRUCT(attrib); - ldap_decode_attrib(mem_ctx, data, &attrib); - add_attrib_to_array_talloc(mem_ctx, &attrib, - attributes, num_attributes); - } -} - -/* Decode a set of LDAP attributes, as found in a search entry */ -static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - ldap_decode_attribs_bare(mem_ctx, data, - attributes, num_attributes); - asn1_end_tag(data); -} - -/* This routine returns LDAP status codes */ - -_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) -{ - uint8_t tag; - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_Integer(data, &msg->messageid); - - if (!asn1_peek_uint8(data, &tag)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - - switch(tag) { - - case ASN1_APPLICATION(LDAP_TAG_BindRequest): { - struct ldap_BindRequest *r = &msg->r.BindRequest; - msg->type = LDAP_TAG_BindRequest; - asn1_start_tag(data, tag); - asn1_read_Integer(data, &r->version); - asn1_read_OctetString_talloc(msg, data, &r->dn); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { - int pwlen; - r->creds.password = ""; - r->mechanism = LDAP_AUTH_MECH_SIMPLE; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - pwlen = asn1_tag_remaining(data); - if (pwlen == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - if (pwlen != 0) { - char *pw = talloc_array(msg, char, pwlen+1); - if (!pw) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, pw, pwlen); - pw[pwlen] = '\0'; - r->creds.password = pw; - } - asn1_end_tag(data); - } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ - asn1_start_tag(data, ASN1_CONTEXT(3)); - r->mechanism = LDAP_AUTH_MECH_SASL; - asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, msg, &tmp_blob); - r->creds.SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->creds.SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->creds.SASL.secblob = NULL; - } - asn1_end_tag(data); - } else { - /* Neither Simple nor SASL bind */ - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_BindResponse): { - struct ldap_BindResponse *r = &msg->r.BindResponse; - msg->type = LDAP_TAG_BindResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->SASL.secblob = NULL; - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { - msg->type = LDAP_TAG_UnbindRequest; - asn1_start_tag(data, tag); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - msg->type = LDAP_TAG_SearchRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->basedn); - asn1_read_enumerated(data, (int *)&(r->scope)); - asn1_read_enumerated(data, (int *)&(r->deref)); - asn1_read_Integer(data, &r->sizelimit); - asn1_read_Integer(data, &r->timelimit); - asn1_read_BOOLEAN(data, &r->attributesonly); - - r->tree = ldap_decode_filter_tree(msg, data); - if (r->tree == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_attributes = 0; - r->attributes = NULL; - - while (asn1_tag_remaining(data) > 0) { - - const char *attr; - if (!asn1_read_OctetString_talloc(msg, data, - &attr)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - if (!add_string_to_array(msg, attr, - &r->attributes, - &r->num_attributes)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - msg->type = LDAP_TAG_SearchResultEntry; - r->attributes = NULL; - r->num_attributes = 0; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { - struct ldap_Result *r = &msg->r.SearchResultDone; - msg->type = LDAP_TAG_SearchResultDone; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - msg->type = LDAP_TAG_SearchResultReference; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->referral); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - msg->type = LDAP_TAG_ModifyRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_mods = 0; - r->mods = NULL; - - while (asn1_tag_remaining(data) > 0) { - struct ldap_mod mod; - int v; - ZERO_STRUCT(mod); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_enumerated(data, &v); - mod.type = v; - ldap_decode_attrib(msg, data, &mod.attrib); - asn1_end_tag(data); - if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { - struct ldap_Result *r = &msg->r.ModifyResponse; - msg->type = LDAP_TAG_ModifyResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddRequest): { - struct ldap_AddRequest *r = &msg->r.AddRequest; - msg->type = LDAP_TAG_AddRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - - r->attributes = NULL; - r->num_attributes = 0; - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddResponse): { - struct ldap_Result *r = &msg->r.AddResponse; - msg->type = LDAP_TAG_AddResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { - struct ldap_DelRequest *r = &msg->r.DelRequest; - int len; - char *dn; - msg->type = LDAP_TAG_DelRequest; - asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - dn = talloc_array(msg, char, len+1); - if (dn == NULL) - break; - asn1_read(data, dn, len); - dn[len] = '\0'; - r->dn = dn; - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_Result *r = &msg->r.DelResponse; - msg->type = LDAP_TAG_DelResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - msg->type = LDAP_TAG_ModifyDNRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_read_OctetString_talloc(msg, data, &r->newrdn); - asn1_read_BOOLEAN(data, &r->deleteolddn); - r->newsuperior = NULL; - if (asn1_tag_remaining(data) > 0) { - int len; - char *newsup; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - newsup = talloc_array(msg, char, len+1); - if (newsup == NULL) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, newsup, len); - newsup[len] = '\0'; - r->newsuperior = newsup; - asn1_end_tag(data); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - msg->type = LDAP_TAG_ModifyDNResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - msg->type = LDAP_TAG_CompareRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_CompareRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(msg, data, &r->attribute); - asn1_read_OctetString(data, msg, &r->value); - if (r->value.data) { - talloc_steal(msg, r->value.data); - } - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { - struct ldap_Result *r = &msg->r.CompareResponse; - msg->type = LDAP_TAG_CompareResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - msg->type = LDAP_TAG_AbandonRequest; - asn1_start_tag(data, tag); - asn1_read_implicit_Integer(data, &r->messageid); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedRequest; - asn1_start_tag(data,tag); - if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } else { - r->oid = NULL; - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - default: - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - msg->controls = NULL; - msg->controls_decoded = NULL; - - if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { - int i = 0; - struct ldb_control **ctrl = NULL; - bool *decoded = NULL; - - asn1_start_tag(data, ASN1_CONTEXT(0)); - - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - DATA_BLOB value; - /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ - - ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); - if (!ctrl) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - decoded = talloc_realloc(msg, decoded, bool, i+1); - if (!decoded) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - if (!ctrl[i]) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { - if (ctrl[i]->critical) { - ctrl[i]->data = NULL; - decoded[i] = false; - i++; - } else { - talloc_free(ctrl[i]); - ctrl[i] = NULL; - } - } else { - decoded[i] = true; - i++; - } - } - - if (ctrl != NULL) { - ctrl[i] = NULL; - } - - msg->controls = ctrl; - msg->controls_decoded = decoded; - - asn1_end_tag(data); - } - - asn1_end_tag(data); - if ((data->has_error) || (data->nesting != NULL)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - return NT_STATUS_OK; -} - - -/* - return NT_STATUS_OK if a blob has enough bytes in it to be a full - ldap packet. Set packet_size if true. -*/ -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) -{ - return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); -} diff --git a/source4/libcli/ldap/ldap_message.h b/source4/libcli/ldap/ldap_message.h deleted file mode 100644 index 47ee724e97..0000000000 --- a/source4/libcli/ldap/ldap_message.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - Unix SMB/CIFS Implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Volker Lendecke 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - -#ifndef _LIBCLI_LDAP_MESSAGE_H_ -#define _LIBCLI_LDAP_MESSAGE_H_ - -#include "libcli/ldap/ldap_errors.h" -#include "lib/ldb/include/ldb.h" - -enum ldap_request_tag { - LDAP_TAG_BindRequest = 0, - LDAP_TAG_BindResponse = 1, - LDAP_TAG_UnbindRequest = 2, - LDAP_TAG_SearchRequest = 3, - LDAP_TAG_SearchResultEntry = 4, - LDAP_TAG_SearchResultDone = 5, - LDAP_TAG_ModifyRequest = 6, - LDAP_TAG_ModifyResponse = 7, - LDAP_TAG_AddRequest = 8, - LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, - LDAP_TAG_ModifyDNRequest = 12, - LDAP_TAG_ModifyDNResponse = 13, - LDAP_TAG_CompareRequest = 14, - LDAP_TAG_CompareResponse = 15, - LDAP_TAG_AbandonRequest = 16, - LDAP_TAG_SearchResultReference = 19, - LDAP_TAG_ExtendedRequest = 23, - LDAP_TAG_ExtendedResponse = 24 -}; - -enum ldap_auth_mechanism { - LDAP_AUTH_MECH_SIMPLE = 0, - LDAP_AUTH_MECH_SASL = 3 -}; - -struct ldap_Result { - int resultcode; - const char *dn; - const char *errormessage; - const char *referral; -}; - -struct ldap_BindRequest { - int version; - const char *dn; - enum ldap_auth_mechanism mechanism; - union { - const char *password; - struct { - const char *mechanism; - DATA_BLOB *secblob;/* optional */ - } SASL; - } creds; -}; - -struct ldap_BindResponse { - struct ldap_Result response; - union { - DATA_BLOB *secblob;/* optional */ - } SASL; -}; - -struct ldap_UnbindRequest { - uint8_t __dummy; -}; - -enum ldap_scope { - LDAP_SEARCH_SCOPE_BASE = 0, - LDAP_SEARCH_SCOPE_SINGLE = 1, - LDAP_SEARCH_SCOPE_SUB = 2 -}; - -enum ldap_deref { - LDAP_DEREFERENCE_NEVER = 0, - LDAP_DEREFERENCE_IN_SEARCHING = 1, - LDAP_DEREFERENCE_FINDING_BASE = 2, - LDAP_DEREFERENCE_ALWAYS -}; - -struct ldap_SearchRequest { - const char *basedn; - enum ldap_scope scope; - enum ldap_deref deref; - uint32_t timelimit; - uint32_t sizelimit; - bool attributesonly; - struct ldb_parse_tree *tree; - int num_attributes; - const char * const *attributes; -}; - -struct ldap_SearchResEntry { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_SearchResRef { - const char *referral; -}; - -enum ldap_modify_type { - LDAP_MODIFY_NONE = -1, - LDAP_MODIFY_ADD = 0, - LDAP_MODIFY_DELETE = 1, - LDAP_MODIFY_REPLACE = 2 -}; - -struct ldap_mod { - enum ldap_modify_type type; - struct ldb_message_element attrib; -}; - -struct ldap_ModifyRequest { - const char *dn; - int num_mods; - struct ldap_mod *mods; -}; - -struct ldap_AddRequest { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_DelRequest { - const char *dn; -}; - -struct ldap_ModifyDNRequest { - const char *dn; - const char *newrdn; - bool deleteolddn; - const char *newsuperior;/* optional */ -}; - -struct ldap_CompareRequest { - const char *dn; - const char *attribute; - DATA_BLOB value; -}; - -struct ldap_AbandonRequest { - uint32_t messageid; -}; - -struct ldap_ExtendedRequest { - const char *oid; - DATA_BLOB *value;/* optional */ -}; - -struct ldap_ExtendedResponse { - struct ldap_Result response; - const char *oid;/* optional */ - DATA_BLOB *value;/* optional */ -}; - -union ldap_Request { - struct ldap_Result GeneralResult; - struct ldap_BindRequest BindRequest; - struct ldap_BindResponse BindResponse; - struct ldap_UnbindRequest UnbindRequest; - struct ldap_SearchRequest SearchRequest; - struct ldap_SearchResEntry SearchResultEntry; - struct ldap_Result SearchResultDone; - struct ldap_SearchResRef SearchResultReference; - struct ldap_ModifyRequest ModifyRequest; - struct ldap_Result ModifyResponse; - struct ldap_AddRequest AddRequest; - struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; - struct ldap_ModifyDNRequest ModifyDNRequest; - struct ldap_Result ModifyDNResponse; - struct ldap_CompareRequest CompareRequest; - struct ldap_Result CompareResponse; - struct ldap_AbandonRequest AbandonRequest; - struct ldap_ExtendedRequest ExtendedRequest; - struct ldap_ExtendedResponse ExtendedResponse; -}; - - -struct ldap_message { - int messageid; - enum ldap_request_tag type; - union ldap_Request r; - struct ldb_control **controls; - bool *controls_decoded; -}; - -struct asn1_data; - -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result); - -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes); - -#endif diff --git a/source4/main.mk b/source4/main.mk index 04f7a36a5f..ee2018fb69 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -50,3 +50,5 @@ mkinclude kdc/config.mk mkinclude ../lib/smbconf/config.mk mkinclude ../lib/async_req/config.mk mkinclude ../libcli/security/config.mk +mkinclude ../libcli/ldap/config.mk + -- cgit From ef0fa403f1c5d670b7991770e7fbb8394879de4b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 16:52:37 +0100 Subject: libcli/ldap: move ldap_errors.h to the toplevel and install it metze --- libcli/ldap/config.mk | 2 +- libcli/ldap/ldap_errors.h | 68 +++++++++++++++++++++++++++++++++++++++ libcli/ldap/ldap_message.h | 2 +- source4/headermap.txt | 1 + source4/libcli/ldap/ldap_errors.h | 66 ------------------------------------- source4/libcli/util/nterr.c | 2 +- 6 files changed, 72 insertions(+), 69 deletions(-) create mode 100644 libcli/ldap/ldap_errors.h delete mode 100644 source4/libcli/ldap/ldap_errors.h diff --git a/libcli/ldap/config.mk b/libcli/ldap/config.mk index 067b6778b7..02397cb43a 100644 --- a/libcli/ldap/config.mk +++ b/libcli/ldap/config.mk @@ -4,4 +4,4 @@ PRIVATE_DEPENDENCIES = ASN1_UTIL LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix ../libcli/ldap/, \ ldap_message.o) -PUBLIC_HEADERS += ../libcli/ldap/ldap_message.h +PUBLIC_HEADERS += ../libcli/ldap/ldap_message.h ../libcli/ldap/ldap_errors.h diff --git a/libcli/ldap/ldap_errors.h b/libcli/ldap/ldap_errors.h new file mode 100644 index 0000000000..fa929c6936 --- /dev/null +++ b/libcli/ldap/ldap_errors.h @@ -0,0 +1,68 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#ifndef _SMB_LDAP_ERRORS_H_ +#define _SMB_LDAP_ERRORS_H_ + +#ifndef LDAP_SUCCESS +enum ldap_result_code { + LDAP_SUCCESS = 0, + LDAP_OPERATIONS_ERROR = 1, + LDAP_PROTOCOL_ERROR = 2, + LDAP_TIME_LIMIT_EXCEEDED = 3, + LDAP_SIZE_LIMIT_EXCEEDED = 4, + LDAP_COMPARE_FALSE = 5, + LDAP_COMPARE_TRUE = 6, + LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, + LDAP_STRONG_AUTH_REQUIRED = 8, + LDAP_REFERRAL = 10, + LDAP_ADMIN_LIMIT_EXCEEDED = 11, + LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12, + LDAP_CONFIDENTIALITY_REQUIRED = 13, + LDAP_SASL_BIND_IN_PROGRESS = 14, + LDAP_NO_SUCH_ATTRIBUTE = 16, + LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17, + LDAP_INAPPROPRIATE_MATCHING = 18, + LDAP_CONSTRAINT_VIOLATION = 19, + LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20, + LDAP_INVALID_ATTRIBUTE_SYNTAX = 21, + LDAP_NO_SUCH_OBJECT = 32, + LDAP_ALIAS_PROBLEM = 33, + LDAP_INVALID_DN_SYNTAX = 34, + LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, + LDAP_INAPPROPRIATE_AUTHENTICATION = 48, + LDAP_INVALID_CREDENTIALS = 49, + LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50, + LDAP_BUSY = 51, + LDAP_UNAVAILABLE = 52, + LDAP_UNWILLING_TO_PERFORM = 53, + LDAP_LOOP_DETECT = 54, + LDAP_NAMING_VIOLATION = 64, + LDAP_OBJECT_CLASS_VIOLATION = 65, + LDAP_NOT_ALLOWED_ON_NON_LEAF = 66, + LDAP_NOT_ALLOWED_ON_RDN = 67, + LDAP_ENTRY_ALREADY_EXISTS = 68, + LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69, + LDAP_AFFECTS_MULTIPLE_DSAS = 71, + LDAP_OTHER = 80 +}; +#endif + +#endif /* _SMB_LDAP_ERRORS_H_ */ diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h index 47ee724e97..672de0d925 100644 --- a/libcli/ldap/ldap_message.h +++ b/libcli/ldap/ldap_message.h @@ -21,7 +21,7 @@ #ifndef _LIBCLI_LDAP_MESSAGE_H_ #define _LIBCLI_LDAP_MESSAGE_H_ -#include "libcli/ldap/ldap_errors.h" +#include "../libcli/ldap/ldap_errors.h" #include "lib/ldb/include/ldb.h" enum ldap_request_tag { diff --git a/source4/headermap.txt b/source4/headermap.txt index 9d8e698f5c..6417603d1d 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -50,6 +50,7 @@ param/share.h: share.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h ../libcli/ldap/ldap_message.h: ldap_message.h +../libcli/ldap/ldap_errors.h: ldap_errors.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/ldap_errors.h b/source4/libcli/ldap/ldap_errors.h deleted file mode 100644 index 17ac43814c..0000000000 --- a/source4/libcli/ldap/ldap_errors.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Unix SMB/CIFS Implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Volker Lendecke 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - -#ifndef _SMB_LDAP_ERRORS_H_ -#define _SMB_LDAP_ERRORS_H_ - -enum ldap_result_code { - LDAP_SUCCESS = 0, - LDAP_OPERATIONS_ERROR = 1, - LDAP_PROTOCOL_ERROR = 2, - LDAP_TIME_LIMIT_EXCEEDED = 3, - LDAP_SIZE_LIMIT_EXCEEDED = 4, - LDAP_COMPARE_FALSE = 5, - LDAP_COMPARE_TRUE = 6, - LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, - LDAP_STRONG_AUTH_REQUIRED = 8, - LDAP_REFERRAL = 10, - LDAP_ADMIN_LIMIT_EXCEEDED = 11, - LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12, - LDAP_CONFIDENTIALITY_REQUIRED = 13, - LDAP_SASL_BIND_IN_PROGRESS = 14, - LDAP_NO_SUCH_ATTRIBUTE = 16, - LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17, - LDAP_INAPPROPRIATE_MATCHING = 18, - LDAP_CONSTRAINT_VIOLATION = 19, - LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20, - LDAP_INVALID_ATTRIBUTE_SYNTAX = 21, - LDAP_NO_SUCH_OBJECT = 32, - LDAP_ALIAS_PROBLEM = 33, - LDAP_INVALID_DN_SYNTAX = 34, - LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, - LDAP_INAPPROPRIATE_AUTHENTICATION = 48, - LDAP_INVALID_CREDENTIALS = 49, - LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50, - LDAP_BUSY = 51, - LDAP_UNAVAILABLE = 52, - LDAP_UNWILLING_TO_PERFORM = 53, - LDAP_LOOP_DETECT = 54, - LDAP_NAMING_VIOLATION = 64, - LDAP_OBJECT_CLASS_VIOLATION = 65, - LDAP_NOT_ALLOWED_ON_NON_LEAF = 66, - LDAP_NOT_ALLOWED_ON_RDN = 67, - LDAP_ENTRY_ALREADY_EXISTS = 68, - LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69, - LDAP_AFFECTS_MULTIPLE_DSAS = 71, - LDAP_OTHER = 80 -}; - -#endif /* _SMB_LDAP_ERRORS_H_ */ diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 8371837dcb..4e7cdf5c3a 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -20,7 +20,7 @@ /* NT error codes. please read nterr.h */ #include "includes.h" -#include "libcli/ldap/ldap_errors.h" +#include "../libcli/ldap/ldap_errors.h" #undef strcasecmp typedef struct -- cgit From 7aaec963c1764869b042240fb5b5d6a339ee052b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:29:59 +0100 Subject: libcli/ldap: fix compiler warnings metze --- libcli/ldap/ldap_message.c | 15 ++++++++++----- libcli/ldap/ldap_message.h | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index e8ec716e64..06052a936a 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -923,13 +923,13 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, ret->u.extended.attr = talloc_strdup(ret, "*"); } ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.data = (uint8_t *)talloc_steal(ret, value); ret->u.extended.value.length = strlen(value); ret->u.extended.dnAttributes = dnAttributes; } else { ret->operation = LDB_OP_EQUALITY; ret->u.equality.attr = talloc_steal(ret, attr); - ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.data = (uint8_t *)talloc_steal(ret, value); ret->u.equality.value.length = strlen(value); } if (!asn1_end_tag(data)) { @@ -1087,13 +1087,17 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { struct ldap_SearchRequest *r = &msg->r.SearchRequest; + int sizelimit, timelimit; + const char **attrs = NULL; msg->type = LDAP_TAG_SearchRequest; asn1_start_tag(data, tag); asn1_read_OctetString_talloc(msg, data, &r->basedn); asn1_read_enumerated(data, (int *)&(r->scope)); asn1_read_enumerated(data, (int *)&(r->deref)); - asn1_read_Integer(data, &r->sizelimit); - asn1_read_Integer(data, &r->timelimit); + asn1_read_Integer(data, &sizelimit); + r->sizelimit = sizelimit; + asn1_read_Integer(data, &timelimit); + r->timelimit = timelimit; asn1_read_BOOLEAN(data, &r->attributesonly); r->tree = ldap_decode_filter_tree(msg, data); @@ -1113,10 +1117,11 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) &attr)) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); if (!add_string_to_array(msg, attr, - &r->attributes, + &attrs, &r->num_attributes)) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } + r->attributes = attrs; asn1_end_tag(data); asn1_end_tag(data); diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h index 672de0d925..d2ce14445d 100644 --- a/libcli/ldap/ldap_message.h +++ b/libcli/ldap/ldap_message.h @@ -160,7 +160,7 @@ struct ldap_CompareRequest { }; struct ldap_AbandonRequest { - uint32_t messageid; + int messageid; }; struct ldap_ExtendedRequest { -- cgit From 18b30e5646d7a484c1714eac9b9ce1f8c1a8241a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:50:43 +0100 Subject: libcli/ldap: move ldap_ndr from source4/ to toplevel metze --- libcli/ldap/config.mk | 10 ++++- libcli/ldap/ldap_ndr.c | 96 ++++++++++++++++++++++++++++++++++++++++++ libcli/ldap/ldap_ndr.h | 12 ++++++ source4/headermap.txt | 2 +- source4/libcli/ldap/config.mk | 7 +-- source4/libcli/ldap/ldap_ndr.c | 96 ------------------------------------------ source4/libcli/ldap/ldap_ndr.h | 12 ------ 7 files changed, 119 insertions(+), 116 deletions(-) create mode 100644 libcli/ldap/ldap_ndr.c create mode 100644 libcli/ldap/ldap_ndr.h delete mode 100644 source4/libcli/ldap/ldap_ndr.c delete mode 100644 source4/libcli/ldap/ldap_ndr.h diff --git a/libcli/ldap/config.mk b/libcli/ldap/config.mk index 02397cb43a..22cad8cfbc 100644 --- a/libcli/ldap/config.mk +++ b/libcli/ldap/config.mk @@ -1,7 +1,15 @@ [SUBSYSTEM::LIBCLI_LDAP_MESSAGE] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB -PRIVATE_DEPENDENCIES = ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL ASN1_UTIL LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix ../libcli/ldap/, \ ldap_message.o) PUBLIC_HEADERS += ../libcli/ldap/ldap_message.h ../libcli/ldap/ldap_errors.h + +[SUBSYSTEM::LIBCLI_LDAP_NDR] +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB NDR_MISC NDR_SECURITY + +LIBCLI_LDAP_NDR_OBJ_FILES = ../libcli/ldap/ldap_ndr.o +PUBLIC_HEADERS += ../libcli/ldap/ldap_ndr.h + diff --git a/libcli/ldap/ldap_ndr.c b/libcli/ldap/ldap_ndr.c new file mode 100644 index 0000000000..dd820ff8d5 --- /dev/null +++ b/libcli/ldap/ldap_ndr.c @@ -0,0 +1,96 @@ +/* + Unix SMB/CIFS mplementation. + + wrap/unwrap NDR encoded elements for ldap calls + + Copyright (C) Andrew Tridgell 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#include "includes.h" +#include "lib/ldb/include/ldb.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "libcli/ldap/ldap_ndr.h" + +/* + encode a NDR uint32 as a ldap filter element +*/ +char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) +{ + uint8_t buf[4]; + struct ldb_val val; + SIVAL(buf, 0, value); + val.data = buf; + val.length = 4; + return ldb_binary_encode(mem_ctx, val); +} + +/* + encode a NDR dom_sid as a ldap filter element +*/ +char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + char *ret; + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return NULL; + } + ret = ldb_binary_encode(mem_ctx, blob); + data_blob_free(&blob); + return ret; +} + + +/* + encode a NDR GUID as a ldap filter element +*/ +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + char *ret; + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return NULL; + } + ret = ldb_binary_encode(mem_ctx, blob); + data_blob_free(&blob); + return ret; +} + +/* + decode a NDR GUID from a ldap filter element +*/ +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + + blob.data = val.data; + blob.length = val.length; + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + talloc_free(val.data); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; +} diff --git a/libcli/ldap/ldap_ndr.h b/libcli/ldap/ldap_ndr.h new file mode 100644 index 0000000000..ee1f702c78 --- /dev/null +++ b/libcli/ldap/ldap_ndr.h @@ -0,0 +1,12 @@ +#ifndef __LIBCLI_LDAP_LDAP_NDR_H__ +#define __LIBCLI_LDAP_LDAP_NDR_H__ + +#include "librpc/gen_ndr/ndr_misc.h" + +char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); +char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); + +#endif /* __LIBCLI_LDAP_LDAP_NDR_H__ */ + diff --git a/source4/headermap.txt b/source4/headermap.txt index 6417603d1d..8287044622 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -51,7 +51,7 @@ param/share.h: share.h ../lib/util/wrap_xattr.h: wrap_xattr.h ../libcli/ldap/ldap_message.h: ldap_message.h ../libcli/ldap/ldap_errors.h: ldap_errors.h -libcli/ldap/ldap_ndr.h: ldap_ndr.h +../libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h auth/session.h: samba/session.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index a1f34a6513..f0c0f5295d 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,7 +1,7 @@ [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ - LDAP_ENCODE LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE + LIBCLI_LDAP_NDR LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ ldap_client.o ldap_bind.o \ @@ -10,8 +10,3 @@ PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c))) -[SUBSYSTEM::LDAP_ENCODE] -PRIVATE_DEPENDENCIES = LIBLDB - -LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_ndr.h diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c deleted file mode 100644 index f0a11ba41f..0000000000 --- a/source4/libcli/ldap/ldap_ndr.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - - wrap/unwrap NDR encoded elements for ldap calls - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - -#include "includes.h" -#include "libcli/ldap/ldap.h" -#include "librpc/gen_ndr/ndr_security.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "libcli/ldap/ldap_ndr.h" - -/* - encode a NDR uint32 as a ldap filter element -*/ -char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) -{ - uint8_t buf[4]; - struct ldb_val val; - SIVAL(buf, 0, value); - val.data = buf; - val.length = 4; - return ldb_binary_encode(mem_ctx, val); -} - -/* - encode a NDR dom_sid as a ldap filter element -*/ -char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NULL; - } - ret = ldb_binary_encode(mem_ctx, blob); - data_blob_free(&blob); - return ret; -} - - -/* - encode a NDR GUID as a ldap filter element -*/ -char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NULL; - } - ret = ldb_binary_encode(mem_ctx, blob); - data_blob_free(&blob); - return ret; -} - -/* - decode a NDR GUID from a ldap filter element -*/ -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - - blob.data = val.data; - blob.length = val.length; - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); - talloc_free(val.data); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - return NT_STATUS_OK; -} diff --git a/source4/libcli/ldap/ldap_ndr.h b/source4/libcli/ldap/ldap_ndr.h deleted file mode 100644 index ee1f702c78..0000000000 --- a/source4/libcli/ldap/ldap_ndr.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __LIBCLI_LDAP_LDAP_NDR_H__ -#define __LIBCLI_LDAP_LDAP_NDR_H__ - -#include "librpc/gen_ndr/ndr_misc.h" - -char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); -char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); -char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); - -#endif /* __LIBCLI_LDAP_LDAP_NDR_H__ */ - -- cgit From 7b1c5c94f6a08108d90a73ba78a91df661d68064 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 14:45:01 +0100 Subject: s4:libcli/ldap: don't use 'void **out' as arguments as the behavior is not defined in C. metze --- source4/libcli/ldap/ldap_controls.c | 49 ++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 109837c2bf..487ea61222 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -28,12 +28,13 @@ struct control_handler { const char *oid; - bool (*decode)(void *mem_ctx, DATA_BLOB in, void **out); + bool (*decode)(void *mem_ctx, DATA_BLOB in, void *_out); bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); }; -static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB attr; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; @@ -77,8 +78,9 @@ static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB attr; DATA_BLOB rule; struct asn1_data *data = asn1_init(mem_ctx); @@ -156,8 +158,9 @@ static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data; struct ldb_extended_dn_control *ledc; @@ -196,8 +199,9 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; @@ -229,8 +233,9 @@ static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; @@ -262,8 +267,9 @@ static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou return true; } -static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; @@ -310,8 +316,9 @@ static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return true; } -static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; @@ -365,8 +372,9 @@ static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ -static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB source_attribute; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; @@ -425,8 +433,9 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -434,8 +443,9 @@ static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -443,8 +453,9 @@ static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -452,8 +463,9 @@ static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -461,8 +473,9 @@ static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void * return true; } -static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -470,8 +483,9 @@ static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB assertion_value, context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; @@ -582,8 +596,9 @@ static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; @@ -1132,7 +1147,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) return true; } -static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) { struct asn1_data *data = asn1_init(mem_ctx); struct dsdb_openldap_dereference_result_control *control; -- cgit From f6b0a99cefaedfa7642af31f8fcc4457bacb07a3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 16:49:26 +0100 Subject: libcli/ldap: move generic ldap control encoding code to ldap_message.c As they can we static there, we pass the specific handlers as parameter where we need to support controls. metze --- libcli/ldap/ldap_message.c | 148 +++++++++++++++++++++++++++++++++++- libcli/ldap/ldap_message.h | 14 +++- source4/ldap_server/ldap_server.c | 4 +- source4/libcli/cldap/cldap.c | 12 +-- source4/libcli/ldap/ldap_client.c | 4 +- source4/libcli/ldap/ldap_controls.c | 131 +------------------------------ 6 files changed, 170 insertions(+), 143 deletions(-) diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index 06052a936a..9b00d0188d 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -84,6 +84,138 @@ static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, return true; } +static bool ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, + const struct ldap_control_handler *handlers, + struct ldb_control *ctrl) +{ + int i; + + if (!handlers) { + return true; + } + + for (i = 0; handlers[i].oid != NULL; i++) { + if (strcmp(handlers[i].oid, ctrl->oid) == 0) { + if (!handlers[i].decode || !handlers[i].decode(mem_ctx, value, &ctrl->data)) { + return false; + } + break; + } + } + if (handlers[i].oid == NULL) { + return false; + } + + return true; +} + +static bool ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, + struct ldb_control *ctrl, DATA_BLOB *value) +{ + DATA_BLOB oid; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + if (!asn1_read_OctetString(data, mem_ctx, &oid)) { + return false; + } + ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); + if (!ctrl->oid) { + return false; + } + + if (asn1_peek_tag(data, ASN1_BOOLEAN)) { + bool critical; + if (!asn1_read_BOOLEAN(data, &critical)) { + return false; + } + ctrl->critical = critical; + } else { + ctrl->critical = false; + } + + ctrl->data = NULL; + + if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { + *value = data_blob(NULL, 0); + goto end_tag; + } + + if (!asn1_read_OctetString(data, mem_ctx, value)) { + return false; + } + +end_tag: + if (!asn1_end_tag(data)) { + return false; + } + + return true; +} + +static bool ldap_encode_control(void *mem_ctx, struct asn1_data *data, + const struct ldap_control_handler *handlers, + struct ldb_control *ctrl) +{ + DATA_BLOB value; + int i; + + if (!handlers) { + return false; + } + + for (i = 0; handlers[i].oid != NULL; i++) { + if (strcmp(handlers[i].oid, ctrl->oid) == 0) { + if (!handlers[i].encode) { + if (ctrl->critical) { + return false; + } else { + /* not encoding this control */ + return true; + } + } + if (!handlers[i].encode(mem_ctx, ctrl->data, &value)) { + return false; + } + break; + } + } + if (handlers[i].oid == NULL) { + return false; + } + + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { + return false; + } + + if (ctrl->critical) { + if (!asn1_write_BOOLEAN(data, ctrl->critical)) { + return false; + } + } + + if (!ctrl->data) { + goto pop_tag; + } + + if (!asn1_write_OctetString(data, value.data, value.length)) { + return false; + } + +pop_tag: + if (!asn1_pop_tag(data)) { + return false; + } + + return true; +} + static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { int i; @@ -244,7 +376,9 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res } } -_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, + const struct ldap_control_handler *control_handlers, + DATA_BLOB *result, TALLOC_CTX *mem_ctx) { struct asn1_data *data = asn1_init(mem_ctx); int i, j; @@ -531,7 +665,9 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CT asn1_push_tag(data, ASN1_CONTEXT(0)); for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { + if (!ldap_encode_control(mem_ctx, data, + control_handlers, + msg->controls[i])) { return false; } } @@ -993,7 +1129,9 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, /* This routine returns LDAP status codes */ -_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, + const struct ldap_control_handler *control_handlers, + struct ldap_message *msg) { uint8_t tag; @@ -1428,7 +1566,9 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (!ldap_decode_control_value(ctrl, value, + control_handlers, + ctrl[i])) { if (ctrl[i]->critical) { ctrl[i]->data = NULL; decoded[i] = false; diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h index d2ce14445d..c50018465c 100644 --- a/libcli/ldap/ldap_message.h +++ b/libcli/ldap/ldap_message.h @@ -207,11 +207,21 @@ struct ldap_message { bool *controls_decoded; }; +struct ldap_control_handler { + const char *oid; + bool (*decode)(void *mem_ctx, DATA_BLOB in, void *_out); + bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); +}; + struct asn1_data; struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, + const struct ldap_control_handler *control_handlers, + struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, + const struct ldap_control_handler *control_handlers, + DATA_BLOB *result, TALLOC_CTX *mem_ctx); NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index da44c02aa8..a924024160 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -104,7 +104,7 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, bool ret; msg = call->replies->msg; - if (!ldap_encode(msg, &b, call)) { + if (!ldap_encode(msg, samba_ldap_control_handlers(), &b, call)) { DEBUG(0,("Failed to encode ldap reply of type %d\n", msg->type)); talloc_free(call); return; @@ -150,7 +150,7 @@ static NTSTATUS ldapsrv_decode(void *private_data, DATA_BLOB blob) return NT_STATUS_NO_MEMORY; } - status = ldap_decode(asn1, msg); + status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); if (!NT_STATUS_IS_OK(status)) { asn1_free(asn1); return status; diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 8d2e2e374c..b18ba12b1f 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -108,7 +108,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } /* this initial decode is used to find the message id */ - status = ldap_decode(asn1, ldap_msg); + status = ldap_decode(asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode ldap message: %s\n", nt_errstr(status))); talloc_free(tmp_ctx); @@ -343,7 +343,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, goto failed; } - if (!ldap_encode(msg, &req->encoded, req)) { + if (!ldap_encode(msg, NULL, &req->encoded, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); goto failed; @@ -396,7 +396,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg->type = LDAP_TAG_SearchResultEntry; msg->r.SearchResultEntry = *io->response; - if (!ldap_encode(msg, &blob1, req)) { + if (!ldap_encode(msg, NULL, &blob1, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; @@ -409,7 +409,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg->type = LDAP_TAG_SearchResultDone; msg->r.SearchResultDone = *io->result; - if (!ldap_encode(msg, &blob2, req)) { + if (!ldap_encode(msg, NULL, &blob2, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; @@ -463,7 +463,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, ldap_msg = talloc(mem_ctx, struct ldap_message); NT_STATUS_HAVE_NO_MEMORY(ldap_msg); - status = ldap_decode(req->asn1, ldap_msg); + status = ldap_decode(req->asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode cldap search reply: %s\n", nt_errstr(status))); talloc_free(req); @@ -479,7 +479,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, *io->out.response = ldap_msg->r.SearchResultEntry; /* decode the 2nd part */ - status = ldap_decode(req->asn1, ldap_msg); + status = ldap_decode(req->asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode cldap search result entry: %s\n", nt_errstr(status))); talloc_free(req); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 3e54d7fff0..304a2e1253 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -200,7 +200,7 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - status = ldap_decode(asn1, msg); + status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); if (!NT_STATUS_IS_OK(status)) { asn1_free(asn1); return status; @@ -608,7 +608,7 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn, msg->messageid = req->messageid; - if (!ldap_encode(msg, &req->data, req)) { + if (!ldap_encode(msg, samba_ldap_control_handlers(), &req->data, req)) { status = NT_STATUS_INTERNAL_ERROR; goto failed; } diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 487ea61222..7949758a80 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -26,12 +26,6 @@ #include "libcli/ldap/ldap_proto.h" #include "dsdb/samdb/samdb.h" -struct control_handler { - const char *oid; - bool (*decode)(void *mem_ctx, DATA_BLOB in, void *_out); - bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); -}; - static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out) { void **out = (void **)_out; @@ -435,7 +429,6 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -445,7 +438,6 @@ static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -455,7 +447,6 @@ static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -465,7 +456,6 @@ static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -475,7 +465,6 @@ static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void * static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -1149,6 +1138,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct dsdb_openldap_dereference_result_control *control; struct dsdb_openldap_dereference_result **r = NULL; @@ -1216,7 +1206,7 @@ static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) return true; } -struct control_handler ldap_known_controls[] = { +static const struct ldap_control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request }, @@ -1240,121 +1230,8 @@ struct control_handler ldap_known_controls[] = { { NULL, NULL, NULL } }; -bool ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) +const struct ldap_control_handler *samba_ldap_control_handlers(void) { - int i; - - for (i = 0; ldap_known_controls[i].oid != NULL; i++) { - if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].decode || !ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { - return false; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { - return false; - } - - return true; + return ldap_known_controls; } -bool ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) -{ - DATA_BLOB oid; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return false; - } - - if (!asn1_read_OctetString(data, mem_ctx, &oid)) { - return false; - } - ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); - if (!ctrl->oid) { - return false; - } - - if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - bool critical; - if (!asn1_read_BOOLEAN(data, &critical)) { - return false; - } - ctrl->critical = critical; - } else { - ctrl->critical = false; - } - - ctrl->data = NULL; - - if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { - *value = data_blob(NULL, 0); - goto end_tag; - } - - if (!asn1_read_OctetString(data, mem_ctx, value)) { - return false; - } - -end_tag: - if (!asn1_end_tag(data)) { - return false; - } - - return true; -} - -bool ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) -{ - DATA_BLOB value; - int i; - - for (i = 0; ldap_known_controls[i].oid != NULL; i++) { - if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].encode) { - if (ctrl->critical) { - return false; - } else { - /* not encoding this control */ - return true; - } - } - if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { - return false; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { - return false; - } - - if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return false; - } - - if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { - return false; - } - - if (ctrl->critical) { - if (!asn1_write_BOOLEAN(data, ctrl->critical)) { - return false; - } - } - - if (!ctrl->data) { - goto pop_tag; - } - - if (!asn1_write_OctetString(data, value.data, value.length)) { - return false; - } - -pop_tag: - if (!asn1_pop_tag(data)) { - return false; - } - - return true; -} -- cgit From 023164f77e36694f4dc7435119f28f42ea0fb0ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 14:23:12 +0100 Subject: s3:Makefile: build libcli/ldap files metze --- source3/Makefile.in | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index a403f143bb..4cd25c8cee 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -444,7 +444,10 @@ LIBSMB_OBJ0 = \ LIBSAMBA_OBJ = $(LIBSMB_OBJ0) \ $(LIBSMB_ERR_OBJ) -CLDAP_OBJ = libads/cldap.o +LIBCLI_LDAP_MESSAGE_OBJ = ../libcli/ldap/ldap_message.o +LIBCLI_LDAP_NDR_OBJ = ../libcli/ldap/ldap_ndr.o + +CLDAP_OBJ = libads/cldap.o $(LIBCLI_LDAP_MESSAGE_OBJ) $(LIBCLI_LDAP_NDR_OBJ) LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clikrb5.o libsmb/clispnego.o ../lib/util/asn1.o \ @@ -756,7 +759,7 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \ nmbd/nmbd_subnetdb.o nmbd/nmbd_winsproxy.o nmbd/nmbd_winsserver.o \ nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o smbd/connection.o -NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ $(LIBNDR_GEN_OBJ0) @@ -935,7 +938,7 @@ NET_OBJ = $(NET_OBJ1) \ $(PRIVILEGES_BASIC_OBJ) @LIBLUA_STATIC@ \ $(LIB_EVENTLOG_OBJ) -CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ +CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \ $(LIBNDR_GEN_OBJ0) @@ -952,24 +955,24 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta torture/denytest.o torture/mangle_test.o SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \ - $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ + $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ lib/wb_reqtrans.o lib/wbclient.o \ @LIBWBCLIENT_STATIC@ \ $(LIBNDR_GEN_OBJ0) -MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) -MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \ - $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) \ + $(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) -NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) @@ -984,7 +987,7 @@ SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ LOG2PCAP_OBJ = utils/log2pcaphex.o -LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \ +LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) @@ -1024,7 +1027,7 @@ REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \ DEBUG2HTML_OBJ = utils/debug2html.o utils/debugparse.o -SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ +SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ $(LIBNDR_GEN_OBJ0) -- cgit From 365925eea308673f15e03d81b69f04b8908468e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 11:37:57 -0800 Subject: Start fixing Solaris build failures. Jeremy. --- source4/heimdal/kuser/kuser_locl.h | 2 +- source4/heimdal/lib/krb5/krb5_locl.h | 2 +- source4/heimdal_build/internal.m4 | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source4/heimdal/kuser/kuser_locl.h b/source4/heimdal/kuser/kuser_locl.h index 21e9776975..eed9e00af6 100644 --- a/source4/heimdal/kuser/kuser_locl.h +++ b/source4/heimdal/kuser/kuser_locl.h @@ -88,7 +88,7 @@ #include #endif -#ifdef LIBINTL +#ifdef HAVE_LIBINTL_H #include #define N_(x,y) gettext(x) #define NP_(x,y) (x) diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index 1a490392a9..ced722f2d9 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -118,7 +118,7 @@ struct sockaddr_dl; #define HEIMDAL_TEXTDOMAIN "heimdal_krb5" -#ifdef LIBINTL +#ifdef HAVE_LIBINTL_H #include #define N_(x,y) dgettext(HEIMDAL_TEXTDOMAIN, x) #else diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index b2f64a6825..50a3c8adda 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -69,7 +69,8 @@ AC_CHECK_HEADERS([ \ ttyname.h \ netinet/in.h \ netinet/in6.h \ - netinet6/in6.h + netinet6/in6.h \ + libintl.h ]) AC_CHECK_FUNCS([ \ -- cgit From dbc79381a87269e8ca0631e001aebb064ab4851b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 11:53:50 +0100 Subject: Convert name_mangle() to use talloc --- source3/include/proto.h | 2 +- source3/libsmb/cliconnect.c | 25 +++++++++++++++++++++---- source3/libsmb/nmblib.c | 15 +++++++++++---- source3/utils/smbfilter.c | 11 +++++++++-- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 3ca94b9192..87dac3e496 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3117,7 +3117,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t, bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name); int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len); void sort_query_replies(char *data, int n, struct in_addr ip); -int name_mangle( char *In, char *Out, char name_type ); +char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type); int name_extract(char *buf,int ofs, fstring name); int name_len(char *s1); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index dabfc398ce..ad11ee0ed4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1642,6 +1642,7 @@ bool cli_session_request(struct cli_state *cli, { char *p; int len = 4; + char *tmp; /* 445 doesn't have session request */ if (cli->port == 445) @@ -1651,14 +1652,30 @@ bool cli_session_request(struct cli_state *cli, memcpy(&(cli->called ), called , sizeof(*called )); /* put in the destination name */ + + tmp = name_mangle(talloc_tos(), cli->called.name, + cli->called.name_type); + if (tmp == NULL) { + return false; + } + p = cli->outbuf+len; - name_mangle(cli->called .name, p, cli->called .name_type); - len += name_len(p); + memcpy(p, tmp, name_len(tmp)); + len += name_len(tmp); + TALLOC_FREE(tmp); /* and my name */ + + tmp = name_mangle(talloc_tos(), cli->calling.name, + cli->calling.name_type); + if (tmp == NULL) { + return false; + } + p = cli->outbuf+len; - name_mangle(cli->calling.name, p, cli->calling.name_type); - len += name_len(p); + memcpy(p, tmp, name_len(tmp)); + len += name_len(tmp); + TALLOC_FREE(tmp); /* send a session request (RFC 1002) */ /* setup the packet length diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 02b13ae63e..5f3eda44fe 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1279,12 +1279,19 @@ static int name_interpret(char *in, fstring name) Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. ****************************************************************************/ -int name_mangle( char *In, char *Out, char name_type ) +char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type) { int i; int len; nstring buf; - char *p = Out; + char *result; + char *p; + + result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2); + if (result == NULL) { + return NULL; + } + p = result; /* Safely copy the input string, In, into buf[]. */ if (strcmp(In,"*") == 0) @@ -1321,7 +1328,7 @@ int name_mangle( char *In, char *Out, char name_type ) p[0] = len; if( len > 0 ) p[len+1] = 0; - return( name_len(Out) ); + return result; case '.': p[0] = len; p += (len + 1); @@ -1333,7 +1340,7 @@ int name_mangle( char *In, char *Out, char name_type ) } } - return( name_len(Out) ); + return result; } /**************************************************************************** diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c index 1fdea818d6..39a264011e 100644 --- a/source3/utils/smbfilter.c +++ b/source3/utils/smbfilter.c @@ -91,8 +91,15 @@ static void filter_request(char *buf) d_printf("sesion_request: %s -> %s\n", name1, name2); if (netbiosname) { - /* replace the destination netbios name */ - name_mangle(netbiosname, buf+4, 0x20); + char *mangled = name_mangle( + talloc_tos(), netbiosname, 0x20); + if (mangled != NULL) { + /* replace the destination netbios + * name */ + memcpy(buf+4, mangled, + name_len(mangled)); + TALLOC_FREE(mangled); + } } } return; -- cgit From c50233695e002d9f7c872821f7b90cdea632dd30 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:47:54 +0100 Subject: Add tevent_req_is_unix_error --- lib/util/tevent_unix.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ lib/util/tevent_unix.h | 27 +++++++++++++++++++++++++++ source3/Makefile.in | 3 ++- 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 lib/util/tevent_unix.c create mode 100644 lib/util/tevent_unix.h diff --git a/lib/util/tevent_unix.c b/lib/util/tevent_unix.c new file mode 100644 index 0000000000..b89d5cd4d4 --- /dev/null +++ b/lib/util/tevent_unix.c @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "tevent_unix.h" +#include "../replace/replace.h" + +bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno) +{ + enum tevent_req_state state; + uint64_t err; + + if (!tevent_req_is_error(req, &state, &err)) { + return false; + } + switch (state) { + case TEVENT_REQ_TIMED_OUT: + *perrno = ETIMEDOUT; + break; + case TEVENT_REQ_NO_MEMORY: + *perrno = ENOMEM; + break; + case TEVENT_REQ_USER_ERROR: + *perrno = err; + break; + default: + *perrno = EINVAL; + break; + } + return true; +} diff --git a/lib/util/tevent_unix.h b/lib/util/tevent_unix.h new file mode 100644 index 0000000000..dc3ffaef33 --- /dev/null +++ b/lib/util/tevent_unix.h @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _TEVENT_UNIX_H +#define _TEVENT_UNIX_H + +#include "../tevent/tevent.h" + +bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno); + +#endif diff --git a/source3/Makefile.in b/source3/Makefile.in index 4cd25c8cee..73b2989421 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -339,7 +339,8 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ ../lib/util/util.o ../lib/util/fsusage.o \ ../lib/util/params.o ../lib/util/talloc_stack.o \ ../lib/util/genrand.o ../lib/util/util_net.o \ - ../lib/util/become_daemon.o ../lib/util/system.o + ../lib/util/become_daemon.o ../lib/util/system.o \ + ../lib/util/tevent_unix.o CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ -- cgit From 70814474f55befc1617e1162a23d14838ba451a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:48:46 +0100 Subject: tevent.h requires bool and uint[16|32|64]_t --- lib/tevent/tevent.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 16fac7327f..33747f0986 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -31,6 +31,7 @@ #include #include #include +#include <../lib/replace/replace.h> struct tevent_context; struct tevent_ops; -- cgit From 39976035ebd669d168afa91274d7e368305bf69d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:49:18 +0100 Subject: Convert async_connect to tevent_req --- lib/async_req/async_sock.c | 54 ++++++++++++++++++++-------------------- lib/async_req/async_sock.h | 11 ++++---- source3/lib/util_sock.c | 29 ++++++++++++---------- source3/lib/wbclient.c | 62 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 93 insertions(+), 63 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 02ae880683..f5e3e5ba33 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -22,6 +22,7 @@ #include "lib/tevent/tevent.h" #include "lib/async_req/async_req.h" #include "lib/async_req/async_sock.h" +#include "lib/util/tevent_unix.h" #include #ifndef TALLOC_FREE @@ -633,17 +634,18 @@ static void async_connect_connected(struct tevent_context *ev, * connect in an async state. This will be reset when the request is finished. */ -struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const struct sockaddr *address, - socklen_t address_len) +struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const struct sockaddr *address, + socklen_t address_len) { - struct async_req *result; + struct tevent_req *result; struct async_connect_state *state; struct tevent_fd *fde; - if (!async_req_setup(mem_ctx, &result, &state, - struct async_connect_state)) { + result = tevent_req_create( + mem_ctx, &state, struct async_connect_state); + if (result == NULL) { return NULL; } @@ -664,8 +666,8 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, state->result = connect(fd, address, address_len); if (state->result == 0) { - state->sys_errno = 0; - goto post_status; + errno = 0; + goto post_errno; } /** @@ -686,22 +688,20 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, async_connect_connected, result); if (fde == NULL) { - state->sys_errno = ENOMEM; - goto post_status; + errno = ENOMEM; + goto post_errno; } return result; post_errno: state->sys_errno = errno; - post_status: fcntl(fd, F_SETFL, state->old_sockflags); - if (!async_post_error(result, ev, state->sys_errno)) { - goto fail; + if (state->sys_errno == 0) { + tevent_req_done(result); + } else { + tevent_req_error(result, state->sys_errno); } - return result; - fail: - TALLOC_FREE(result); - return NULL; + return tevent_req_post(result, ev); } /** @@ -716,10 +716,10 @@ static void async_connect_connected(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *priv) { - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); + struct tevent_req *req = talloc_get_type_abort( + priv, struct tevent_req); struct async_connect_state *state = talloc_get_type_abort( - req->private_data, struct async_connect_state); + req->private_state, struct async_connect_state); TALLOC_FREE(fde); @@ -743,27 +743,27 @@ static void async_connect_connected(struct tevent_context *ev, DEBUG(10, ("connect returned %s\n", strerror(errno))); fcntl(state->fd, F_SETFL, state->old_sockflags); - async_req_error(req, state->sys_errno); + tevent_req_error(req, state->sys_errno); return; } state->sys_errno = 0; - async_req_done(req); + tevent_req_done(req); } -int async_connect_recv(struct async_req *req, int *perrno) +int async_connect_recv(struct tevent_req *req, int *perrno) { struct async_connect_state *state = talloc_get_type_abort( - req->private_data, struct async_connect_state); + req->private_state, struct async_connect_state); int err; fcntl(state->fd, F_SETFL, state->old_sockflags); - - if (async_req_is_errno(req, &err)) { + if (tevent_req_is_unix_error(req, &err)) { *perrno = err; return -1; } + if (state->sys_errno == 0) { return 0; } diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index c8739e9ed6..784571ed5a 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -35,11 +35,12 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); -struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const struct sockaddr *address, - socklen_t address_len); -int async_connect_recv(struct async_req *req, int *perrno); + +struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const struct sockaddr *address, + socklen_t address_len); +int async_connect_recv(struct tevent_req *req, int *perrno); struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buffer, size_t length, diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index c46aa2ac49..83e8a9d355 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -953,7 +953,7 @@ struct open_socket_out_state { int wait_nsec; }; -static void open_socket_out_connected(struct async_req *subreq); +static void open_socket_out_connected(struct tevent_req *subreq); static int open_socket_out_state_destructor(struct open_socket_out_state *s) { @@ -974,7 +974,8 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, int timeout) { char addr[INET6_ADDRSTRLEN]; - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct open_socket_out_state *state; NTSTATUS status; @@ -1026,13 +1027,14 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, (struct sockaddr *)&state->ss, state->salen); if ((subreq == NULL) - || !async_req_set_timeout(subreq, state->ev, - timeval_set(0, state->wait_nsec))) { + || !tevent_req_set_endtime( + subreq, state->ev, + timeval_current_ofs(0, state->wait_nsec))) { status = NT_STATUS_NO_MEMORY; goto post_status; } subreq->async.fn = open_socket_out_connected; - subreq->async.priv = result; + subreq->async.private_data = result; return result; post_status: @@ -1045,18 +1047,18 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, return NULL; } -static void open_socket_out_connected(struct async_req *subreq) +static void open_socket_out_connected(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct open_socket_out_state *state = talloc_get_type_abort( req->private_data, struct open_socket_out_state); - int err; + int ret; int sys_errno; - err = async_connect_recv(subreq, &sys_errno); + ret = async_connect_recv(subreq, &sys_errno); TALLOC_FREE(subreq); - if (err == 0) { + if (ret == 0) { async_req_done(req); return; } @@ -1083,13 +1085,14 @@ static void open_socket_out_connected(struct async_req *subreq) if (async_req_nomem(subreq, req)) { return; } - if (!async_req_set_timeout(subreq, state->ev, - timeval_set(0, state->wait_nsec))) { + if (!tevent_req_set_endtime( + subreq, state->ev, + timeval_current_ofs(0, state->wait_nsec))) { async_req_error(req, ENOMEM); return; } subreq->async.fn = open_socket_out_connected; - subreq->async.priv = req; + subreq->async.private_data = req; return; } diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c index 4d3a609530..b8d55a944a 100644 --- a/source3/lib/wbclient.c +++ b/source3/lib/wbclient.c @@ -147,17 +147,30 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx) return result; } +struct wb_connect_state { + int dummy; +}; + +static void wbc_connect_connected(struct tevent_req *subreq); + static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct wb_context *wb_ctx, - const char *dir) + struct tevent_context *ev, + struct wb_context *wb_ctx, + const char *dir) { - struct async_req *req; + struct async_req *result; + struct tevent_req *subreq; + struct wb_connect_state *state; struct sockaddr_un sunaddr; struct stat st; char *path = NULL; wbcErr wbc_err; + if (!async_req_setup(mem_ctx, &result, &state, + struct wb_connect_state)) { + return NULL; + } + if (wb_ctx->fd != -1) { close(wb_ctx->fd); wb_ctx->fd = -1; @@ -205,33 +218,46 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, goto post_status; } - req = async_connect_send(mem_ctx, ev, wb_ctx->fd, - (struct sockaddr *)&sunaddr, - sizeof(sunaddr)); - if (req == NULL) { + subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd, + (struct sockaddr *)&sunaddr, + sizeof(sunaddr)); + if (subreq == NULL) { goto nomem; } - if (!async_req_set_timeout(req, ev, timeval_set(30, 0))) { - TALLOC_FREE(req); + subreq->async.fn = wbc_connect_connected; + subreq->async.private_data = result; + + if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) { goto nomem; } - return req; + return result; nomem: wbc_err = WBC_ERR_NO_MEMORY; post_status: - req = async_req_new(mem_ctx); - if (req == NULL) { - return NULL; - } - if (async_post_error(req, ev, wbc_err)) { - return req; + if (async_post_error(result, ev, wbc_err)) { + return result; } - TALLOC_FREE(req); + TALLOC_FREE(result); return NULL; } +static void wbc_connect_connected(struct tevent_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.private_data, struct async_req); + int res, err; + + res = async_connect_recv(subreq, &err); + TALLOC_FREE(subreq); + if (res == -1) { + async_req_error(req, map_wbc_err_from_errno(err)); + return; + } + async_req_done(req); +} + static wbcErr wb_connect_recv(struct async_req *req) { return async_req_simple_recv_wbcerr(req); -- cgit From 76c6330dfb78e536bc7620719d12859ff7418c36 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 20:16:32 +0100 Subject: Add async writev --- lib/async_req/async_sock.c | 105 +++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 4 ++ 2 files changed, 109 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index f5e3e5ba33..380fea5908 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -771,3 +771,108 @@ int async_connect_recv(struct tevent_req *req, int *perrno) *perrno = state->sys_errno; return -1; } + +struct writev_state { + struct tevent_context *ev; + int fd; + struct iovec *iov; + int count; + size_t total_size; +}; + +static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, struct iovec *iov, int count) +{ + struct tevent_req *result; + struct writev_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct writev_state); + if (result == NULL) { + return NULL; + } + state->ev = ev; + state->fd = fd; + state->total_size = 0; + state->count = count; + state->iov = (struct iovec *)talloc_memdup( + state, iov, sizeof(struct iovec) * count); + if (state->iov == NULL) { + goto fail; + } + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, writev_handler, + result); + if (fde == NULL) { + goto fail; + } + return result; + + fail: + TALLOC_FREE(result); + return NULL; +} + +static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct writev_state *state = talloc_get_type_abort( + req->private_state, struct writev_state); + size_t to_write, written; + int i; + + to_write = 0; + + for (i=0; icount; i++) { + to_write += state->iov[i].iov_len; + } + + written = sys_writev(state->fd, state->iov, state->count); + if (written == -1) { + tevent_req_error(req, errno); + return; + } + if (written == 0) { + tevent_req_error(req, EOF); + return; + } + state->total_size += written; + + if (written == to_write) { + tevent_req_done(req); + return; + } + + /* + * We've written less than we were asked to, drop stuff from + * state->iov. + */ + + while (written > 0) { + if (written < state->iov[0].iov_len) { + state->iov[0].iov_base = + (char *)state->iov[0].iov_base + written; + state->iov[0].iov_len -= written; + break; + } + written = state->iov[0].iov_len; + state->iov += 1; + state->count -= 1; + } +} + +ssize_t writev_recv(struct tevent_req *req, int *perrno) +{ + struct writev_state *state = talloc_get_type_abort( + req->private_state, struct writev_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->total_size; +} diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 784571ed5a..3d70673c17 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -52,4 +52,8 @@ struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int flags); ssize_t recvall_recv(struct async_req *req, int *perr); +struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, struct iovec *iov, int count); +ssize_t writev_recv(struct tevent_req *req, int *perrno); + #endif -- cgit From 53b059fc52c0908d4f8cbc98510b10d96850dcc6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 21:41:57 +0100 Subject: Use async writev in wb_req_write --- source3/lib/wb_reqtrans.c | 74 ++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 52 deletions(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 9bf6f29105..1c2d09318d 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -237,90 +237,60 @@ wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, } struct req_write_state { - struct winbindd_request *wb_req; - struct tevent_context *ev; - int fd; + struct iovec iov[2]; }; -static void wb_req_write_main(struct async_req *subreq); -static void wb_req_write_extra(struct async_req *subreq); +static void wb_req_write_done(struct tevent_req *subreq); struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct winbindd_request *wb_req) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct req_write_state *state; + int count = 1; if (!async_req_setup(mem_ctx, &result, &state, struct req_write_state)) { return NULL; } - state->fd = fd; - state->ev = ev; - state->wb_req = wb_req; - subreq = sendall_send(state, state->ev, state->fd, state->wb_req, - sizeof(struct winbindd_request), 0); - if (subreq == NULL) { - goto nomem; + state->iov[0].iov_base = wb_req; + state->iov[0].iov_len = sizeof(struct winbindd_request); + + if (wb_req->extra_len != 0) { + state->iov[1].iov_base = wb_req->extra_data.data; + state->iov[1].iov_len = wb_req->extra_len; + count = 2; } - subreq->async.fn = wb_req_write_main; - subreq->async.priv = result; + subreq = writev_send(state, ev, fd, state->iov, count); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = wb_req_write_done; + subreq->async.private_data = result; return result; - nomem: + fail: TALLOC_FREE(result); return NULL; } -static void wb_req_write_main(struct async_req *subreq) +static void wb_req_write_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct req_write_state *state = talloc_get_type_abort( - req->private_data, struct req_write_state); + subreq->async.private_data, struct async_req); int err; ssize_t ret; - ret = sendall_recv(subreq, &err); + ret = writev_recv(subreq, &err); TALLOC_FREE(subreq); if (ret < 0) { async_req_error(req, map_wbc_err_from_errno(err)); return; } - - if (state->wb_req->extra_len == 0) { - async_req_done(req); - return; - } - - subreq = sendall_send(state, state->ev, state->fd, - state->wb_req->extra_data.data, - state->wb_req->extra_len, 0); - if (async_req_nomem(subreq, req)) { - return; - } - - subreq->async.fn = wb_req_write_extra; - subreq->async.priv = req; -} - -static void wb_req_write_extra(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - int err; - ssize_t ret; - - ret = sendall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; - } - async_req_done(req); } -- cgit From ae1a0b553414dafbe7a0aa38581a352b202e1411 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 21:55:03 +0100 Subject: Use async writev for wb_resp_write --- source3/lib/wb_reqtrans.c | 76 ++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 1c2d09318d..1be7239092 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -451,91 +451,61 @@ wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, } struct resp_write_state { - struct winbindd_response *wb_resp; - struct tevent_context *ev; - int fd; + struct iovec iov[2]; }; -static void wb_resp_write_main(struct async_req *subreq); -static void wb_resp_write_extra(struct async_req *subreq); +static void wb_resp_write_done(struct tevent_req *subreq); struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct winbindd_response *wb_resp) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct resp_write_state *state; + int count = 1; if (!async_req_setup(mem_ctx, &result, &state, struct resp_write_state)) { return NULL; } - state->fd = fd; - state->ev = ev; - state->wb_resp = wb_resp; - subreq = sendall_send(state, state->ev, state->fd, state->wb_resp, - sizeof(struct winbindd_response), 0); - if (subreq == NULL) { - goto nomem; + state->iov[0].iov_base = wb_resp; + state->iov[0].iov_len = sizeof(struct winbindd_response); + + if (wb_resp->length > sizeof(struct winbindd_response)) { + state->iov[1].iov_base = wb_resp->extra_data.data; + state->iov[1].iov_len = + wb_resp->length - sizeof(struct winbindd_response); + count = 2; } - subreq->async.fn = wb_resp_write_main; - subreq->async.priv = result; + subreq = writev_send(state, ev, fd, state->iov, count); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = wb_resp_write_done; + subreq->async.private_data = result; return result; - nomem: + fail: TALLOC_FREE(result); return NULL; } -static void wb_resp_write_main(struct async_req *subreq) +static void wb_resp_write_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct resp_write_state *state = talloc_get_type_abort( - req->private_data, struct resp_write_state); + subreq->async.private_data, struct async_req); int err; ssize_t ret; - ret = sendall_recv(subreq, &err); + ret = writev_recv(subreq, &err); TALLOC_FREE(subreq); if (ret < 0) { async_req_error(req, map_wbc_err_from_errno(err)); return; } - - if (state->wb_resp->length == sizeof(struct winbindd_response)) { - async_req_done(req); - return; - } - - subreq = sendall_send( - state, state->ev, state->fd, - state->wb_resp->extra_data.data, - state->wb_resp->length - sizeof(struct winbindd_response), 0); - if (async_req_nomem(subreq, req)) { - return; - } - - subreq->async.fn = wb_resp_write_extra; - subreq->async.priv = req; -} - -static void wb_resp_write_extra(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - int err; - ssize_t ret; - - ret = sendall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (err < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; - } - async_req_done(req); } -- cgit From 70f788ba7ea7ffa4d0808d0a299d98ee894a89a2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 22:01:35 +0100 Subject: Use async_writev in np_write --- source3/rpc_server/srv_pipe_hnd.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 6dead2d264..d33d7f64b2 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1171,13 +1171,12 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name, struct np_write_state { struct event_context *ev; struct np_proxy_state *p; - const uint8_t *data; - size_t len; + struct iovec iov; ssize_t nwritten; }; static void np_write_trigger(struct async_req *req); -static void np_write_done(struct async_req *subreq); +static void np_write_done(struct tevent_req *subreq); struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct fake_file_handle *handle, @@ -1218,8 +1217,8 @@ struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, state->ev = ev; state->p = p; - state->data = data; - state->len = len; + state->iov.iov_base = CONST_DISCARD(void *, data); + state->iov.iov_len = len; if (!async_req_enqueue(p->write_queue, ev, result, np_write_trigger)) { @@ -1242,27 +1241,26 @@ static void np_write_trigger(struct async_req *req) { struct np_write_state *state = talloc_get_type_abort( req->private_data, struct np_write_state); - struct async_req *subreq; + struct tevent_req *subreq; - subreq = sendall_send(state, state->ev, state->p->fd, state->data, - state->len, 0); + subreq = writev_send(state, state->ev, state->p->fd, &state->iov, 1); if (async_req_nomem(subreq, req)) { return; } subreq->async.fn = np_write_done; - subreq->async.priv = req; + subreq->async.private_data = req; } -static void np_write_done(struct async_req *subreq) +static void np_write_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct np_write_state *state = talloc_get_type_abort( req->private_data, struct np_write_state); ssize_t received; int err; - received = sendall_recv(subreq, &err); + received = writev_recv(subreq, &err); if (received < 0) { async_req_nterror(req, map_nt_error_from_unix(err)); return; -- cgit From e50075a5804204068f07cb82337d3a251b368245 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 22:03:06 +0100 Subject: Remove async sendall --- lib/async_req/async_sock.c | 111 --------------------------------------------- lib/async_req/async_sock.h | 5 -- 2 files changed, 116 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 380fea5908..33f8ebe192 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -34,7 +34,6 @@ */ enum async_syscall_type { ASYNC_SYSCALL_SEND, - ASYNC_SYSCALL_SENDALL, ASYNC_SYSCALL_RECV, ASYNC_SYSCALL_RECVALL, ASYNC_SYSCALL_CONNECT @@ -55,13 +54,6 @@ struct async_syscall_state { size_t length; int flags; } param_send; - struct param_sendall { - int fd; - const void *buffer; - size_t length; - int flags; - size_t sent; - } param_sendall; struct param_recv { int fd; void *buffer; @@ -337,109 +329,6 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "sendall" syscall group - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the send - * @param[in] flags Can only be TEVENT_FD_WRITE here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_sendall_callback(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - struct param_sendall *p = &state->param.param_sendall; - - if (state->syscall_type != ASYNC_SYSCALL_SENDALL) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = send(p->fd, - (const char *)p->buffer + p->sent, - p->length - p->sent, p->flags); - state->sys_errno = errno; - - if (state->result.result_ssize_t == -1) { - async_req_error(req, state->sys_errno); - return; - } - - if (state->result.result_ssize_t == 0) { - async_req_error(req, EOF); - return; - } - - p->sent += state->result.result_ssize_t; - if (p->sent > p->length) { - async_req_error(req, EIO); - return; - } - - if (p->sent == p->length) { - TALLOC_FREE(state->fde); - async_req_done(req); - } -} - -/** - * @brief Send all bytes to a socket - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to send to - * @param[in] buffer The buffer to send - * @param[in] length How many bytes to send - * @param[in] flags flags passed to send(2) - * - * async_sendall calls send(2) as long as it is necessary to send all of the - * "length" bytes - */ - -struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_SENDALL, - fd, TEVENT_FD_WRITE, async_sendall_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_sendall.fd = fd; - state->param.param_sendall.buffer = buffer; - state->param.param_sendall.length = length; - state->param.param_sendall.flags = flags; - state->param.param_sendall.sent = 0; - - return result; -} - -ssize_t sendall_recv(struct async_req *req, int *perr) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - int err; - - err = async_req_simple_recv_errno(req); - - if (err != 0) { - *perr = err; - return -1; - } - - return state->result.result_ssize_t; -} - /** * fde event handler for the "recv" syscall * @param[in] ev The event context that sent us here diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 3d70673c17..6a862c45c6 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,11 +42,6 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, socklen_t address_len); int async_connect_recv(struct tevent_req *req, int *perrno); -struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags); -ssize_t sendall_recv(struct async_req *req, int *perr); - struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); -- cgit From f9df355befdef7c424ebc70abfeb696de095235e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:12:56 +0100 Subject: Fix async writev --- lib/async_req/async_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 33f8ebe192..67776ff67f 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -727,7 +727,7 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, return; } if (written == 0) { - tevent_req_error(req, EOF); + tevent_req_error(req, EPIPE); return; } state->total_size += written; -- cgit From 4021029cddddcb23c41cd7f8b711f3a8d83c3931 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:13:34 +0100 Subject: Add async read_packet --- lib/async_req/async_sock.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 10 ++++ 2 files changed, 128 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 67776ff67f..02e4c9eb4b 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -765,3 +765,121 @@ ssize_t writev_recv(struct tevent_req *req, int *perrno) } return state->total_size; } + +struct read_packet_state { + int fd; + uint8_t *buf; + size_t nread; + ssize_t (*more)(uint8_t *buf, size_t buflen, void *private_data); + void *private_data; +}; + +static void read_packet_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t initial, + ssize_t (*more)(uint8_t *buf, + size_t buflen, + void *private_data), + void *private_data) +{ + struct tevent_req *result; + struct read_packet_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct read_packet_state); + if (result == NULL) { + return NULL; + } + state->fd = fd; + state->nread = 0; + state->more = more; + state->private_data = private_data; + + state->buf = talloc_array(state, uint8_t, initial); + if (state->buf == NULL) { + goto fail; + } + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_packet_handler, + result); + if (fde == NULL) { + goto fail; + } + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void read_packet_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct read_packet_state *state = talloc_get_type_abort( + req->private_state, struct read_packet_state); + size_t total = talloc_get_size(state->buf); + ssize_t nread, more; + uint8_t *tmp; + + nread = read(state->fd, state->buf+state->nread, total-state->nread); + if (nread == -1) { + tevent_req_error(req, errno); + return; + } + if (nread == 0) { + tevent_req_error(req, EPIPE); + return; + } + + state->nread += nread; + if (state->nread < total) { + /* Come back later */ + return; + } + + /* + * We got what was initially requested. See if "more" asks for -- more. + */ + if (state->more == NULL) { + /* Nobody to ask, this is a async read_data */ + tevent_req_done(req); + return; + } + + more = state->more(state->buf, total, state->private_data); + if (more == -1) { + /* We got an invalid packet, tell the caller */ + tevent_req_error(req, EIO); + return; + } + if (more == 0) { + /* We're done, full packet received */ + tevent_req_done(req); + return; + } + + tmp = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t, total+more); + if (tevent_req_nomem(tmp, req)) { + return; + } + state->buf = tmp; +} + +ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **pbuf, int *perrno) +{ + struct read_packet_state *state = talloc_get_type_abort( + req->private_state, struct read_packet_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + *pbuf = talloc_move(mem_ctx, &state->buf); + return talloc_get_size(*pbuf); +} diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 6a862c45c6..0cf4e4ecf5 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -51,4 +51,14 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct iovec *iov, int count); ssize_t writev_recv(struct tevent_req *req, int *perrno); +struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t initial, + ssize_t (*more)(uint8_t *buf, + size_t buflen, + void *private_data), + void *private_data); +ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **pbuf, int *perrno); + #endif -- cgit From 5d653f69de27ee22137333bc319ae2d7e60e56b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:17:15 +0100 Subject: Replace read_pkt by read_packet in np_read --- source3/rpc_server/srv_pipe_hnd.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index d33d7f64b2..33e89c8acb 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1314,7 +1314,7 @@ struct np_read_state { }; static void np_read_trigger(struct async_req *req); -static void np_read_done(struct async_req *subreq); +static void np_read_done(struct tevent_req *subreq); struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct fake_file_handle *handle, @@ -1391,28 +1391,28 @@ static void np_read_trigger(struct async_req *req) { struct np_read_state *state = talloc_get_type_abort( req->private_data, struct np_read_state); - struct async_req *subreq; + struct tevent_req *subreq; - subreq = read_pkt_send(state, state->ev, state->p->fd, RPC_HEADER_LEN, - rpc_frag_more_fn, NULL); + subreq = read_packet_send(state, state->ev, state->p->fd, + RPC_HEADER_LEN, rpc_frag_more_fn, NULL); if (async_req_nomem(subreq, req)) { return; } subreq->async.fn = np_read_done; - subreq->async.priv = req; + subreq->async.private_data = req; } -static void np_read_done(struct async_req *subreq) +static void np_read_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct np_read_state *state = talloc_get_type_abort( req->private_data, struct np_read_state); ssize_t received; size_t thistime; int err; - received = read_pkt_recv(subreq, state->p, &state->p->msg, &err); + received = read_packet_recv(subreq, state->p, &state->p->msg, &err); TALLOC_FREE(subreq); if (received == -1) { async_req_nterror(req, map_nt_error_from_unix(err)); -- cgit From 202a31d96d9abaf09716bad4c57caf38ef03cc81 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:18:04 +0100 Subject: Remove read_pkt --- source3/include/proto.h | 9 ----- source3/lib/util.c | 99 ------------------------------------------------- 2 files changed, 108 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 87dac3e496..daeef637ca 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1243,15 +1243,6 @@ bool is_valid_policy_hnd(const POLICY_HND *hnd); bool policy_hnd_equal(const struct policy_handle *hnd1, const struct policy_handle *hnd2); const char *strip_hostname(const char *s); -struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - int fd, size_t initial, - ssize_t (*more)(uint8_t *buf, size_t buflen, - void *priv), - void *priv); -ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx, - uint8_t **pbuf, int *perr); - /* The following definitions come from lib/util_file.c */ diff --git a/source3/lib/util.c b/source3/lib/util.c index cda1fb474d..89f7be8e6c 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -3145,102 +3145,3 @@ const char *strip_hostname(const char *s) return s; } - -struct read_pkt_state { - struct event_context *ev; - int fd; - uint8_t *buf; - ssize_t (*more)(uint8_t *buf, size_t buflen, void *priv); - void *priv; -}; - -static void read_pkt_done(struct async_req *subreq); - -struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - int fd, size_t initial, - ssize_t (*more)(uint8_t *buf, size_t buflen, - void *priv), - void *priv) -{ - struct async_req *result, *subreq; - struct read_pkt_state *state; - - if (!async_req_setup(mem_ctx, &result, &state, - struct read_pkt_state)) { - return NULL; - } - state->ev = ev; - state->fd = fd; - state->more = more; - - state->buf = talloc_array(state, uint8_t, initial); - if (state->buf == NULL) { - goto fail; - } - subreq = recvall_send(state, ev, fd, state->buf, initial, 0); - if (subreq == NULL) { - goto fail; - } - subreq->async.fn = read_pkt_done; - subreq->async.priv = result; - return result; - fail: - TALLOC_FREE(result); - return NULL; -} - -static void read_pkt_done(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct read_pkt_state *state = talloc_get_type_abort( - req->private_data, struct read_pkt_state); - size_t current_size; - ssize_t received; - ssize_t more; - int err; - - received = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (received == -1) { - async_req_error(req, err); - return; - } - current_size = talloc_get_size(state->buf); - - more = state->more(state->buf, current_size, state->priv); - if (more < 0) { - async_req_error(req, EIO); - return; - } - if (more == 0) { - async_req_done(req); - return; - } - state->buf = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t, - current_size + more); - if (async_req_nomem(state->buf, req)) { - return; - } - subreq = recvall_send(state, state->ev, state->fd, - state->buf + current_size, more, 0); - if (async_req_nomem(subreq, req)) { - return; - } - subreq->async.fn = read_pkt_done; - subreq->async.priv = req; -} - -ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx, - uint8_t **pbuf, int *perr) -{ - struct read_pkt_state *state = talloc_get_type_abort( - req->private_data, struct read_pkt_state); - - if (async_req_is_errno(req, perr)) { - return -1; - } - *pbuf = talloc_move(mem_ctx, &state->buf); - return talloc_get_size(*pbuf); -} -- cgit From 008901827058251a31de99426858f87c77bcf23b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:06:56 +0100 Subject: Use read_packet for wb_req_read --- source3/lib/wb_reqtrans.c | 128 +++++++++++++--------------------------------- 1 file changed, 36 insertions(+), 92 deletions(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 1be7239092..76b0f53717 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -27,9 +27,7 @@ struct req_read_state { struct winbindd_request *wb_req; - struct tevent_context *ev; size_t max_extra_data; - int fd; }; bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err) @@ -83,145 +81,91 @@ wbcErr async_req_simple_recv_wbcerr(struct async_req *req) return WBC_ERR_SUCCESS; } -static void wb_req_read_len(struct async_req *subreq); -static void wb_req_read_main(struct async_req *subreq); -static void wb_req_read_extra(struct async_req *subreq); +static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data); +static void wb_req_read_done(struct tevent_req *subreq); struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, size_t max_extra_data) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct req_read_state *state; if (!async_req_setup(mem_ctx, &result, &state, struct req_read_state)) { return NULL; } - state->fd = fd; - state->ev = ev; state->max_extra_data = max_extra_data; - state->wb_req = talloc(state, struct winbindd_request); - if (state->wb_req == NULL) { - goto nomem; - } - subreq = recvall_send(state, ev, state->fd, &(state->wb_req->length), - sizeof(state->wb_req->length), 0); + subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state); if (subreq == NULL) { goto nomem; } - subreq->async.fn = wb_req_read_len; - subreq->async.priv = result; + subreq->async.fn = wb_req_read_done; + subreq->async.private_data = result; return result; - nomem: TALLOC_FREE(result); return NULL; } -static void wb_req_read_len(struct async_req *subreq) +static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); struct req_read_state *state = talloc_get_type_abort( - req->private_data, struct req_read_state); - int err; - ssize_t ret; + private_data, struct req_read_state); + struct winbindd_request *req = (struct winbindd_request *)buf; - ret = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; + if (buflen == 4) { + if (req->length != sizeof(struct winbindd_request)) { + DEBUG(0, ("wb_req_read_len: Invalid request size " + "received: %d (expected %d)\n", + (int)req->length, + (int)sizeof(struct winbindd_request))); + return -1; + } + return sizeof(struct winbindd_request) - 4; } - if (state->wb_req->length != sizeof(struct winbindd_request)) { - DEBUG(0, ("wb_req_read_len: Invalid request size received: " - "%d (expected %d)\n", (int)state->wb_req->length, - (int)sizeof(struct winbindd_request))); - async_req_error(req, WBC_ERR_INVALID_RESPONSE); - return; - } - - subreq = recvall_send( - req, state->ev, state->fd, (uint32 *)(state->wb_req)+1, - sizeof(struct winbindd_request) - sizeof(uint32), 0); - if (async_req_nomem(subreq, req)) { - return; + if ((state->max_extra_data != 0) + && (req->extra_len > state->max_extra_data)) { + DEBUG(3, ("Got request with %d bytes extra data on " + "unprivileged socket\n", (int)req->extra_len)); + return -1; } - subreq->async.fn = wb_req_read_main; - subreq->async.priv = req; + return req->extra_len; } -static void wb_req_read_main(struct async_req *subreq) +static void wb_req_read_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct req_read_state *state = talloc_get_type_abort( req->private_data, struct req_read_state); int err; ssize_t ret; + uint8_t *buf; - ret = recvall_recv(subreq, &err); + ret = read_packet_recv(subreq, state, &buf, &err); TALLOC_FREE(subreq); - if (ret < 0) { + if (ret == -1) { async_req_error(req, map_wbc_err_from_errno(err)); return; } - if ((state->max_extra_data != 0) - && (state->wb_req->extra_len > state->max_extra_data)) { - DEBUG(3, ("Got request with %d bytes extra data on " - "unprivileged socket\n", - (int)state->wb_req->extra_len)); - async_req_error(req, WBC_ERR_INVALID_RESPONSE); - return; - } - - if (state->wb_req->extra_len == 0) { - async_req_done(req); - return; - } - - state->wb_req->extra_data.data = TALLOC_ARRAY( - state->wb_req, char, state->wb_req->extra_len + 1); - if (async_req_nomem(state->wb_req->extra_data.data, req)) { - return; - } - - state->wb_req->extra_data.data[state->wb_req->extra_len] = 0; - - subreq = recvall_send( - req, state->ev, state->fd, state->wb_req->extra_data.data, - state->wb_req->extra_len, 0); - if (async_req_nomem(subreq, req)) { - return; - } - - subreq->async.fn = wb_req_read_extra; - subreq->async.priv = req; -} + state->wb_req = (struct winbindd_request *)buf; -static void wb_req_read_extra(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - int err; - ssize_t ret; - - ret = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; + if (state->wb_req->extra_len != 0) { + state->wb_req->extra_data.data = + (char *)buf + sizeof(struct winbindd_request); + } else { + state->wb_req->extra_data.data = NULL; } async_req_done(req); } - wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, struct winbindd_request **preq) { -- cgit From 5766bf896cf85d17023410addb540ebbbef366dd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:18:29 +0100 Subject: Use read_packet for wb_resp_read --- source3/lib/wb_reqtrans.c | 119 +++++++++++----------------------------------- 1 file changed, 29 insertions(+), 90 deletions(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 76b0f53717..a5adf8f108 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -245,40 +245,29 @@ wbcErr wb_req_write_recv(struct async_req *req) struct resp_read_state { struct winbindd_response *wb_resp; - struct tevent_context *ev; - size_t max_extra_data; - int fd; }; -static void wb_resp_read_len(struct async_req *subreq); -static void wb_resp_read_main(struct async_req *subreq); -static void wb_resp_read_extra(struct async_req *subreq); +static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data); +static void wb_resp_read_done(struct tevent_req *subreq); struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct resp_read_state *state; if (!async_req_setup(mem_ctx, &result, &state, struct resp_read_state)) { return NULL; } - state->fd = fd; - state->ev = ev; - state->wb_resp = talloc(state, struct winbindd_response); - if (state->wb_resp == NULL) { - goto nomem; - } - subreq = recvall_send(state, ev, state->fd, &(state->wb_resp->length), - sizeof(state->wb_resp->length), 0); + subreq = read_packet_send(state, ev, fd, 4, wb_resp_more, state); if (subreq == NULL) { goto nomem; } - - subreq->async.fn = wb_resp_read_len; - subreq->async.priv = result; + subreq->async.fn = wb_resp_read_done; + subreq->async.private_data = result; return result; nomem: @@ -286,100 +275,50 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, return NULL; } -static void wb_resp_read_len(struct async_req *subreq) +static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct resp_read_state *state = talloc_get_type_abort( - req->private_data, struct resp_read_state); - int err; - ssize_t ret; - - ret = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; - } + struct winbindd_response *resp = (struct winbindd_response *)buf; - if (state->wb_resp->length < sizeof(struct winbindd_response)) { - DEBUG(0, ("wb_resp_read_len: Invalid response size received: " - "%d (expected at least%d)\n", - (int)state->wb_resp->length, - (int)sizeof(struct winbindd_response))); - async_req_error(req, WBC_ERR_INVALID_RESPONSE); - return; - } - - subreq = recvall_send( - req, state->ev, state->fd, (uint32 *)(state->wb_resp)+1, - sizeof(struct winbindd_response) - sizeof(uint32), 0); - if (async_req_nomem(subreq, req)) { - return; + if (buflen == 4) { + if (resp->length < sizeof(struct winbindd_response)) { + DEBUG(0, ("wb_resp_read_len: Invalid response size " + "received: %d (expected at least%d)\n", + (int)resp->length, + (int)sizeof(struct winbindd_response))); + return -1; + } } - - subreq->async.fn = wb_resp_read_main; - subreq->async.priv = req; + return resp->length - 4; } -static void wb_resp_read_main(struct async_req *subreq) +static void wb_resp_read_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct resp_read_state *state = talloc_get_type_abort( req->private_data, struct resp_read_state); + uint8_t *buf; int err; ssize_t ret; - size_t extra_len; - ret = recvall_recv(subreq, &err); + ret = read_packet_recv(subreq, state, &buf, &err); TALLOC_FREE(subreq); - if (ret < 0) { + if (ret == -1) { async_req_error(req, map_wbc_err_from_errno(err)); return; } - extra_len = state->wb_resp->length - sizeof(struct winbindd_response); - if (extra_len == 0) { - async_req_done(req); - return; - } - - state->wb_resp->extra_data.data = TALLOC_ARRAY( - state->wb_resp, char, extra_len+1); - if (async_req_nomem(state->wb_resp->extra_data.data, req)) { - return; - } - ((char *)state->wb_resp->extra_data.data)[extra_len] = 0; - - subreq = recvall_send( - req, state->ev, state->fd, state->wb_resp->extra_data.data, - extra_len, 0); - if (async_req_nomem(subreq, req)) { - return; - } - - subreq->async.fn = wb_resp_read_extra; - subreq->async.priv = req; -} - -static void wb_resp_read_extra(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - int err; - ssize_t ret; + state->wb_resp = (struct winbindd_response *)buf; - ret = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; + if (state->wb_resp->length > sizeof(struct winbindd_response)) { + state->wb_resp->extra_data.data = + (char *)buf + sizeof(struct winbindd_response); + } else { + state->wb_resp->extra_data.data = NULL; } async_req_done(req); } - wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presp) { -- cgit From bbbdfa20566a607e0fdfdd190bb12bc3130e8bee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:20:24 +0100 Subject: Remove unused recvall --- lib/async_req/async_sock.c | 110 --------------------------------------------- lib/async_req/async_sock.h | 5 --- 2 files changed, 115 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 02e4c9eb4b..86f89c159a 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -35,7 +35,6 @@ enum async_syscall_type { ASYNC_SYSCALL_SEND, ASYNC_SYSCALL_RECV, - ASYNC_SYSCALL_RECVALL, ASYNC_SYSCALL_CONNECT }; @@ -60,13 +59,6 @@ struct async_syscall_state { size_t length; int flags; } param_recv; - struct param_recvall { - int fd; - void *buffer; - size_t length; - int flags; - size_t received; - } param_recvall; struct param_connect { /** * connect needs to be done on a nonblocking @@ -397,108 +389,6 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "recvall" syscall group - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the recv - * @param[in] flags Can only be TEVENT_FD_READ here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_recvall_callback(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - struct param_recvall *p = &state->param.param_recvall; - - if (state->syscall_type != ASYNC_SYSCALL_RECVALL) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = recv(p->fd, - (char *)p->buffer + p->received, - p->length - p->received, p->flags); - state->sys_errno = errno; - - if (state->result.result_ssize_t == -1) { - async_req_error(req, state->sys_errno); - return; - } - - if (state->result.result_ssize_t == 0) { - async_req_error(req, EIO); - return; - } - - p->received += state->result.result_ssize_t; - if (p->received > p->length) { - async_req_error(req, EIO); - return; - } - - if (p->received == p->length) { - TALLOC_FREE(state->fde); - async_req_done(req); - } -} - -/** - * Receive a specified number of bytes from a socket - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to recv from - * @param[in] buffer The buffer to recv into - * @param[in] length How many bytes to recv - * @param[in] flags flags passed to recv(2) - * - * async_recvall will call recv(2) until "length" bytes are received - */ - -struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_RECVALL, - fd, TEVENT_FD_READ, async_recvall_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_recvall.fd = fd; - state->param.param_recvall.buffer = buffer; - state->param.param_recvall.length = length; - state->param.param_recvall.flags = flags; - state->param.param_recvall.received = 0; - - return result; -} - -ssize_t recvall_recv(struct async_req *req, int *perr) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - int err; - - err = async_req_simple_recv_errno(req); - - if (err != 0) { - *perr = err; - return -1; - } - - return state->result.result_ssize_t; -} - struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 0cf4e4ecf5..bfa23d7836 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,11 +42,6 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, socklen_t address_len); int async_connect_recv(struct tevent_req *req, int *perrno); -struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags); -ssize_t recvall_recv(struct async_req *req, int *perr); - struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct iovec *iov, int count); ssize_t writev_recv(struct tevent_req *req, int *perrno); -- cgit From 08f028f179f474f83d46b1a23d1cfbd8848b68b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:21:27 +0100 Subject: Remove unused param_connect struct --- lib/async_req/async_sock.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 86f89c159a..7bb52767af 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -35,7 +35,6 @@ enum async_syscall_type { ASYNC_SYSCALL_SEND, ASYNC_SYSCALL_RECV, - ASYNC_SYSCALL_CONNECT }; /** @@ -59,16 +58,6 @@ struct async_syscall_state { size_t length; int flags; } param_recv; - struct param_connect { - /** - * connect needs to be done on a nonblocking - * socket. Keep the old flags around - */ - long old_sockflags; - int fd; - const struct sockaddr *address; - socklen_t address_len; - } param_connect; } param; union { -- cgit From a60480b71ad7cdaa495b7624f04bc477a3330cbf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 08:53:01 +0100 Subject: Add more conventional async_send --- lib/async_req/async_sock.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 6 +++++ 2 files changed, 73 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 7bb52767af..323d285729 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -378,6 +378,73 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } +struct async_send_state { + int fd; + const void *buf; + size_t len; + int flags; + ssize_t sent; +}; + +static void async_send_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const void *buf, size_t len, + int flags) +{ + struct tevent_req *result; + struct async_send_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct async_send_state); + if (result == NULL) { + return result; + } + state->fd = fd; + state->buf = buf; + state->len = len; + state->flags = flags; + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, async_send_handler, + result); + if (fde == NULL) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + +static void async_send_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct async_send_state *state = talloc_get_type_abort( + req->private_state, struct async_send_state); + + state->sent = send(state->fd, state->buf, state->len, state->flags); + if (state->sent == -1) { + tevent_req_error(req, errno); + return; + } + tevent_req_done(req); +} + +ssize_t async_send_recv(struct tevent_req *req, int *perrno) +{ + struct async_send_state *state = talloc_get_type_abort( + req->private_state, struct async_send_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->sent; +} + struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index bfa23d7836..89dabdac4c 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -36,6 +36,12 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); +struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const void *buf, size_t len, + int flags); +ssize_t async_send_recv(struct tevent_req *req, int *perrno); + struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const struct sockaddr *address, -- cgit From 25df6d74131b8b9bd8924ca70eb891ff97d3ddfd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 08:56:35 +0100 Subject: Add more conventional async_recv --- lib/async_req/async_sock.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 5 ++++ 2 files changed, 72 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 323d285729..3563421e0e 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -445,6 +445,73 @@ ssize_t async_send_recv(struct tevent_req *req, int *perrno) return state->sent; } +struct async_recv_state { + int fd; + void *buf; + size_t len; + int flags; + ssize_t received; +}; + +static void async_recv_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t len, int flags) +{ + struct tevent_req *result; + struct async_recv_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct async_recv_state); + if (result == NULL) { + return result; + } + state->fd = fd; + state->buf = buf; + state->len = len; + state->flags = flags; + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, async_recv_handler, + result); + if (fde == NULL) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + +static void async_recv_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct async_recv_state *state = talloc_get_type_abort( + req->private_state, struct async_recv_state); + + state->received = recv(state->fd, state->buf, state->len, + state->flags); + if (state->received == -1) { + tevent_req_error(req, errno); + return; + } + tevent_req_done(req); +} + +ssize_t async_recv_recv(struct tevent_req *req, int *perrno) +{ + struct async_recv_state *state = talloc_get_type_abort( + req->private_state, struct async_recv_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->received; +} + struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 89dabdac4c..bfc4346d39 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,6 +42,11 @@ struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, int flags); ssize_t async_send_recv(struct tevent_req *req, int *perrno); +struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t len, int flags); +ssize_t async_recv_recv(struct tevent_req *req, int *perrno); + struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const struct sockaddr *address, -- cgit From e3746ac922c29f90d0dbb23a76f5387daf21c8c3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Feb 2009 21:08:07 +0100 Subject: Fix some C++ warnings --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 33 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 0fa638e863..f1c063ed90 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -47,7 +47,8 @@ struct server_pipe_state { static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerReqChallenge *r) { - struct server_pipe_state *pipe_state = dce_call->context->private_data; + struct server_pipe_state *pipe_state = + (struct server_pipe_state *)dce_call->context->private_data; ZERO_STRUCTP(r->out.return_credentials); @@ -76,7 +77,8 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerAuthenticate3 *r) { - struct server_pipe_state *pipe_state = dce_call->context->private_data; + struct server_pipe_state *pipe_state = + (struct server_pipe_state *)dce_call->context->private_data; struct creds_CredentialState *creds; void *sam_ctx; struct samr_Password *mach_pwd; @@ -148,7 +150,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* pull the user attributes */ - num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs, + num_records = gendb_search((struct ldb_context *)sam_ctx, + mem_ctx, NULL, &msgs, + trust_dom_attrs, "(&(trustPartner=%s)(objectclass=trustedDomain))", encoded_account); @@ -179,7 +183,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* pull the user attributes */ - num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs, + num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx, + NULL, &msgs, attrs, "(&(sAMAccountName=%s)(objectclass=user))", ldb_binary_encode_string(mem_ctx, account_name)); @@ -848,13 +853,14 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C return WERR_DS_SERVICE_UNAVAILABLE; } - domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx, + domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx, r->in.domainname); if (domain_dn == NULL) { return WERR_DS_SERVICE_UNAVAILABLE; } - ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, + domain_dn, &res, attrs); if (ret != 1) { return WERR_NO_SUCH_DOMAIN; } @@ -1218,13 +1224,15 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); } - domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx, + domain_dn = samdb_dns_domain_to_dn((struct ldb_context *)sam_ctx, + mem_ctx, r->in.domain_name); if (domain_dn == NULL) { return WERR_DS_SERVICE_UNAVAILABLE; } - ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, + domain_dn, &res, attrs); if (ret != 1) { return WERR_NO_SUCH_DOMAIN; } @@ -1377,9 +1385,11 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce return WERR_GENERAL_FAILURE; } - partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx); + partitions_basedn = samdb_partitions_dn((struct ldb_context *)sam_ctx, + mem_ctx); - ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL, + &dom_res, dom_attrs); if (ret == -1) { return WERR_GENERAL_FAILURE; } @@ -1387,7 +1397,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce return WERR_GENERAL_FAILURE; } - ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs, + ret = gendb_search((struct ldb_context *)sam_ctx, mem_ctx, + partitions_basedn, &ref_res, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))", ldb_dn_get_linearized(dom_res[0]->dn)); if (ret == -1) { -- cgit From 3a88316e233079199117731756d35d0aea4670e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 12:19:06 -0800 Subject: Fix the build. Looks like no one ever compiled this on a system with a libintl.h before. Jeremy. --- source4/client/mount.cifs.c | 2 ++ source4/heimdal/kuser/kinit.c | 2 ++ source4/heimdal/lib/krb5/context.c | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/source4/client/mount.cifs.c b/source4/client/mount.cifs.c index 7167859d7b..899c90cefd 100644 --- a/source4/client/mount.cifs.c +++ b/source4/client/mount.cifs.c @@ -313,8 +313,10 @@ int main(int argc, char ** argv) FILE * pmntfile; /* setlocale(LC_ALL, ""); +#if defined(LOCALEDIR) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); */ +#endif if(argc && argv) { thisprogram = argv[0]; diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c index d1ef776716..fbb2d2287b 100644 --- a/source4/heimdal/kuser/kinit.c +++ b/source4/heimdal/kuser/kinit.c @@ -726,8 +726,10 @@ main (int argc, char **argv) setprogname (argv[0]); setlocale (LC_ALL, ""); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR); textdomain("heimdal_kuser"); +#endif ret = krb5_init_context (&context); if (ret == KRB5_CONFIG_BADFORMAT) diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index aa35a184c0..127dfa117d 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -295,7 +295,9 @@ krb5_init_context(krb5_context *context) *context = NULL; /* should have a run_once */ +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(HEIMDAL_TEXTDOMAIN, HEIMDAL_LOCALEDIR); +#endif p = calloc(1, sizeof(*p)); if(!p) @@ -836,20 +838,30 @@ krb5_init_ets(krb5_context context) { if(context->et_list == NULL){ krb5_add_et_list(context, initialize_krb5_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_asn1_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_heim_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_k524_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR); +#endif #ifdef PKINIT krb5_add_et_list(context, initialize_hx_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR); +#endif #endif } } -- cgit From e4e1b1a0bb2ed333ed42e8cfab0349589a420029 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:18:22 +0100 Subject: s3-spoolss: add rpccli_spoolss_getprinterdriver2 convenience wrapper. Guenther --- source3/include/proto.h | 11 +++++++ source3/rpc_client/cli_spoolss.c | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index daeef637ca..b41a405655 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5465,6 +5465,17 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli, const char *printername, uint32_t access_desired, struct policy_handle *handle); +WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *architecture, + uint32_t level, + uint32_t offered, + uint32_t client_major_version, + uint32_t client_minor_version, + union spoolss_DriverInfo *info, + uint32_t *server_major_version, + uint32_t *server_minor_version); WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 6ad3af1f4e..b8f17416cc 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -75,6 +75,68 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli, return WERR_OK; } +/********************************************************************** + convencience wrapper around rpccli_spoolss_GetPrinterDriver2 +**********************************************************************/ + +WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *architecture, + uint32_t level, + uint32_t offered, + uint32_t client_major_version, + uint32_t client_minor_version, + union spoolss_DriverInfo *info, + uint32_t *server_major_version, + uint32_t *server_minor_version) +{ + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; + + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + } + + status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx, + handle, + architecture, + level, + (offered > 0) ? &buffer : NULL, + offered, + client_major_version, + client_minor_version, + info, + &needed, + server_major_version, + server_minor_version, + &werror); + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + + status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx, + handle, + architecture, + level, + &buffer, + offered, + client_major_version, + client_minor_version, + info, + &needed, + server_major_version, + server_minor_version, + &werror); + } + + return werror; +} + /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ -- cgit From e4c1841d1a0b9daa32901f1eb21a3dd504a7677c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:20:30 +0100 Subject: s3-rpcclient: use rpccli_spoolss_getprinterdriver2 wrapper. Guenther --- source3/rpcclient/cmd_spoolss.c | 86 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 8 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index bb9d0e6d6c..99838f6396 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -986,6 +986,68 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1) return; } +/**************************************************************************** +****************************************************************************/ + +static void display_print_driver1(struct spoolss_DriverInfo1 *r) +{ + if (!r) { + return; + } + + printf("Printer Driver Info 1:\n"); + printf("\tDriver Name: [%s]\n\n", r->driver_name); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_print_driver2(struct spoolss_DriverInfo2 *r) +{ + if (!r) { + return; + } + + printf("Printer Driver Info 2:\n"); + printf("\tVersion: [%x]\n", r->version); + printf("\tDriver Name: [%s]\n", r->driver_name); + printf("\tArchitecture: [%s]\n", r->architecture); + printf("\tDriver Path: [%s]\n", r->driver_path); + printf("\tDatafile: [%s]\n", r->data_file); + printf("\tConfigfile: [%s]\n\n", r->config_file); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_print_driver3(struct spoolss_DriverInfo3 *r) +{ + int i; + + if (!r) { + return; + } + + printf("Printer Driver Info 3:\n"); + printf("\tVersion: [%x]\n", r->version); + printf("\tDriver Name: [%s]\n", r->driver_name); + printf("\tArchitecture: [%s]\n", r->architecture); + printf("\tDriver Path: [%s]\n", r->driver_path); + printf("\tDatafile: [%s]\n", r->data_file); + printf("\tConfigfile: [%s]\n\n", r->config_file); + printf("\tHelpfile: [%s]\n\n", r->help_file); + + for (i=0; r->dependent_files[i] != NULL; i++) { + printf("\tDependentfiles: [%s]\n", r->dependent_files[i]); + } + + printf("\n"); + + printf("\tMonitorname: [%s]\n", r->monitor_name); + printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype); +} + + /**************************************************************************** ****************************************************************************/ @@ -997,10 +1059,12 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, WERROR werror; uint32 info_level = 3; bool opened_hnd = False; - PRINTER_DRIVER_CTR ctr; const char *printername; uint32 i; bool success = False; + union spoolss_DriverInfo info; + uint32_t server_major_version; + uint32_t server_minor_version; if ((argc == 1) || (argc > 3)) { @@ -1032,10 +1096,16 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, for (i=0; archi_table[i].long_archi!=NULL; i++) { - werror = rpccli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level, - archi_table[i].long_archi, archi_table[i].version, - &ctr); - + werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx, + &pol, + archi_table[i].long_archi, + info_level, + 0, /* offered */ + archi_table[i].version, + 2, + &info, + &server_major_version, + &server_minor_version); if (!W_ERROR_IS_OK(werror)) continue; @@ -1047,13 +1117,13 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, switch (info_level) { case 1: - display_print_driver_1 (ctr.info1); + display_print_driver1(&info.info1); break; case 2: - display_print_driver_2 (ctr.info2); + display_print_driver2(&info.info2); break; case 3: - display_print_driver_3 (ctr.info3); + display_print_driver3(&info.info3); break; default: printf("unknown info level %d\n", info_level); -- cgit From 3ceffcaa467d72890d6148f600ce7c2ddadb63d5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:23:56 +0100 Subject: s3-net: use rpccli_spoolss_AddPrinterDriver and rpccli_spoolss_getprinterdriver2 wrapper. Guenther --- source3/utils/net_rpc_printer.c | 145 ++++++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 56 deletions(-) diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index bb8747ede3..17df69597f 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -50,6 +50,33 @@ static const struct table_node archi_table[]= { Printer info level 3 display function. ****************************************************************************/ +static void display_print_driver3(struct spoolss_DriverInfo3 *r) +{ + int i; + + if (!r) { + return; + } + + printf("Printer Driver Info 3:\n"); + printf("\tVersion: [%x]\n", r->version); + printf("\tDriver Name: [%s]\n", r->driver_name); + printf("\tArchitecture: [%s]\n", r->architecture); + printf("\tDriver Path: [%s]\n", r->driver_path); + printf("\tDatafile: [%s]\n", r->data_file); + printf("\tConfigfile: [%s]\n\n", r->config_file); + printf("\tHelpfile: [%s]\n\n", r->help_file); + + for (i=0; r->dependent_files[i] != NULL; i++) { + printf("\tDependentfiles: [%s]\n", r->dependent_files[i]); + } + + printf("\n"); + + printf("\tMonitorname: [%s]\n", r->monitor_name); + printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype); +} + static void display_print_driver_3(DRIVER_INFO_3 *i1) { fstring name = ""; @@ -513,7 +540,7 @@ static NTSTATUS net_copy_driverfile(struct net_context *c, TALLOC_CTX *mem_ctx, struct cli_state *cli_share_src, struct cli_state *cli_share_dst, - char *file, const char *short_archi) { + const char *file, const char *short_archi) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; const char *p; @@ -523,6 +550,10 @@ static NTSTATUS net_copy_driverfile(struct net_context *c, char *filename; char *tok; + if (!file) { + return NT_STATUS_OK; + } + /* scroll through the file until we have the part beyond archi_table.short_archi */ p = file; @@ -617,67 +648,47 @@ static NTSTATUS copy_print_driver_3(struct net_context *c, TALLOC_CTX *mem_ctx, struct cli_state *cli_share_src, struct cli_state *cli_share_dst, - const char *short_archi, DRIVER_INFO_3 *i1) + const char *short_archi, + struct spoolss_DriverInfo3 *r) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - int length = 0; - bool valid = true; + int i; - fstring name = ""; - fstring driverpath = ""; - fstring datafile = ""; - fstring configfile = ""; - fstring helpfile = ""; - fstring dependentfiles = ""; - - if (i1 == NULL) + if (r == NULL) { return nt_status; - - rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE); - rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE); - rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE); - rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE); - rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE); - + } if (c->opt_verbose) d_printf("copying driver: [%s], for architecture: [%s], version: [%d]\n", - name, short_archi, i1->version); + r->driver_name, short_archi, r->version); nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, - driverpath, short_archi); + r->driver_path, short_archi); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, - datafile, short_archi); + r->data_file, short_archi); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, - configfile, short_archi); + r->config_file, short_archi); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, - helpfile, short_archi); + r->help_file, short_archi); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; - while (valid) { + for (i=0; r->dependent_files[i] != NULL; i++) { - rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE); - length += strlen(dependentfiles)+1; - - if (strlen(dependentfiles) > 0) { - - nt_status = net_copy_driverfile(c, mem_ctx, - cli_share_src, cli_share_dst, - dependentfiles, short_archi); - if (!NT_STATUS_IS_OK(nt_status)) - return nt_status; - } else { - valid = false; + nt_status = net_copy_driverfile(c, mem_ctx, + cli_share_src, cli_share_dst, + r->dependent_files[i], short_archi); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } } @@ -930,15 +941,23 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, const char *env, int version, - PRINTER_DRIVER_CTR *ctr) + union spoolss_DriverInfo *info) { WERROR result; + uint32_t server_major_version; + uint32_t server_minor_version; /* getprinterdriver call */ - result = rpccli_spoolss_getprinterdriver( - pipe_hnd, mem_ctx, hnd, level, - env, version, ctr); - + result = rpccli_spoolss_getprinterdriver2(pipe_hnd, mem_ctx, + hnd, + env, + level, + 0, + version, + 2, + info, + &server_major_version, + &server_minor_version); if (!W_ERROR_IS_OK(result)) { DEBUG(1,("cannot get driver (for architecture: %s): %s\n", env, win_errstr(result))); @@ -955,13 +974,31 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr) + union spoolss_DriverInfo *info) { WERROR result; + NTSTATUS status; + struct spoolss_AddDriverInfoCtr info_ctr; - /* addprinterdriver call */ - result = rpccli_spoolss_addprinterdriver(pipe_hnd, mem_ctx, level, ctr); + info_ctr.level = level; + + switch (level) { + case 2: + info_ctr.info.info2 = (struct spoolss_AddDriverInfo2 *)&info->info2; + break; + case 3: + info_ctr.info.info3 = (struct spoolss_AddDriverInfo3 *)&info->info3; + break; + default: + printf("unsupported info level: %d\n", level); + return false; + } + /* addprinterdriver call */ + status = rpccli_spoolss_AddPrinterDriver(pipe_hnd, mem_ctx, + pipe_hnd->srv_name_slash, + &info_ctr, + &result); /* be more verbose */ if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) { printf("You are not allowed to add drivers\n"); @@ -1785,15 +1822,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, bool got_dst_driver_share = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_DRIVER_CTR drv_ctr_src, drv_ctr_dst; + union spoolss_DriverInfo drv_info_src; PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst; struct cli_state *cli_dst = NULL; struct cli_state *cli_share_src = NULL; struct cli_state *cli_share_dst = NULL; - fstring drivername = ""; + const char *drivername = NULL; - ZERO_STRUCT(drv_ctr_src); - ZERO_STRUCT(drv_ctr_dst); ZERO_STRUCT(info_ctr_enum); ZERO_STRUCT(info_ctr_dst); @@ -1890,15 +1925,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, /* getdriver src */ if (!net_spoolss_getprinterdriver(pipe_hnd, mem_ctx, &hnd_src, level, archi_table[i].long_archi, - archi_table[i].version, &drv_ctr_src)) + archi_table[i].version, &drv_info_src)) continue; - rpcstr_pull(drivername, drv_ctr_src.info3->name.buffer, - sizeof(drivername), -1, STR_TERMINATE); + drivername = drv_info_src.info3.driver_name; if (c->opt_verbose) - display_print_driver_3(drv_ctr_src.info3); - + display_print_driver3(&drv_info_src.info3); /* check arch dir */ nt_status = check_arch_dir(cli_share_dst, archi_table[i].short_archi); @@ -1909,13 +1942,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, /* copy driver-files */ nt_status = copy_print_driver_3(c, mem_ctx, cli_share_src, cli_share_dst, archi_table[i].short_archi, - drv_ctr_src.info3); + &drv_info_src.info3); if (!NT_STATUS_IS_OK(nt_status)) goto done; /* adddriver dst */ - if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_ctr_src)) { + if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_info_src)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } -- cgit From 5ffa03dcd879e59f3e810fbb8833cb9a3e9afcca Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:26:09 +0100 Subject: s3-spoolss: remove old rpccli_spoolss_getprinterdriver wrapper. Guenther --- source3/include/proto.h | 4 -- source3/rpc_client/cli_spoolss.c | 79 --------------------------------------- source3/rpc_parse/parse_spoolss.c | 27 ------------- 3 files changed, 110 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index b41a405655..08840bd7cc 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5487,10 +5487,6 @@ WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr, uint32 command); -WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - const char *env, int version, PRINTER_DRIVER_CTR *ctr); WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index b8f17416cc..8a8dabeba4 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -801,85 +801,6 @@ WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - const char *env, int version, PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDRIVER2 in; - SPOOL_R_GETPRINTERDRIVER2 out; - RPC_BUFFER buffer; - fstring server; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - fstrcpy(server, cli->desthost); - strupper_m(server); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinterdriver2( &in, pol, env, level, - version, 2, &buffer, offered); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinterdriver2, - spoolss_io_r_getprinterdriver2, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinterdriver2( &in, pol, env, level, - version, 2, &buffer, offered); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinterdriver2, - spoolss_io_r_getprinterdriver2, - WERR_GENERAL_FAILURE ); - } - - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - switch (level) { - case 1: - if (!decode_printer_driver_1(mem_ctx, out.buffer, 1, &ctr->info1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_driver_2(mem_ctx, out.buffer, 1, &ctr->info2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 3: - if (!decode_printer_driver_3(mem_ctx, out.buffer, 1, &ctr->info3)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 435bb1bd80..4ffa121e1c 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -2050,33 +2050,6 @@ uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info) return size; } -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, - const POLICY_HND *hnd, - const fstring architecture, - uint32 level, uint32 clientmajor, uint32 clientminor, - RPC_BUFFER *buffer, uint32 offered) -{ - if (q_u == NULL) - return False; - - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture); - - q_u->level=level; - q_u->clientmajorversion=clientmajor; - q_u->clientminorversion=clientminor; - - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} - /******************************************************************* * read a structure. * called from spoolss_getprinterdriver2 (srv_spoolss.c) -- cgit From 9bb1bea53709dd32b8c3bf6032b38d9f95c8c379 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 14:07:29 -0800 Subject: s3: Fix a bug that prevent core files from being created Removed an erroneous free() that was causing the corepath to be NULL during dump_core(). This prevented dump_core() from actually calling abort() to create a core file. The bug was introduced in December by: 07e0094365e8dc360a83eec2e7cf9b1d5d8d6d00 --- source3/lib/fault.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/lib/fault.c b/source3/lib/fault.c index a1530987f3..8c4a45bbc9 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -157,7 +157,6 @@ void dump_core_setup(const char *progname) return; } - SAFE_FREE(corepath); SAFE_FREE(logbase); #ifdef HAVE_GETRLIMIT -- cgit From 3777978eb466bf0e5268851f2820f8f91ff1bf85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Feb 2009 00:43:23 +0100 Subject: s3-rpcclient: use rpccli_spoolss_AddPrinterDriver. Guenther --- source3/include/proto.h | 1 - source3/rpcclient/cmd_spoolss.c | 119 +++++++++++++++++++++++----------------- 2 files changed, 69 insertions(+), 51 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 08840bd7cc..95c4c1659b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6239,7 +6239,6 @@ bool init_service_op_table( void ); /* The following definitions come from rpcclient/cmd_spoolss.c */ -void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch); /* The following definitions come from rpcclient/cmd_srvsvc.c */ diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 99838f6396..17ff818de6 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1289,7 +1289,9 @@ static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli, /**************************************************************************** ****************************************************************************/ -void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch) +static void set_drv_info_3_env(TALLOC_CTX *mem_ctx, + struct spoolss_AddDriverInfo3 *info, + const char *arch) { int i; @@ -1299,7 +1301,7 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch) if (strcmp(arch, archi_table[i].short_archi) == 0) { info->version = archi_table[i].version; - init_unistr (&info->architecture, archi_table[i].long_archi); + info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi); break; } } @@ -1318,8 +1320,9 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch) Needed to handle the empty parameter string denoted by "NULL" *************************************************************************/ -static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest, - char **saveptr) +static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str, + const char *delim, const char **dest, + char **saveptr) { char *ptr; @@ -1330,70 +1333,80 @@ static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest, parameter because two consecutive delimiters will not return an empty string. See man strtok(3) for details */ - if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) + if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) { ptr = NULL; + } - if (dest != NULL) - init_unistr(dest, ptr); + if (dest != NULL) { + *dest = talloc_strdup(mem_ctx, ptr); + } return ptr; } /******************************************************************************** - fill in the members of a DRIVER_INFO_3 struct using a character + fill in the members of a spoolss_AddDriverInfo3 struct using a character string in the form of :::\ :::\ : *******************************************************************************/ -static bool init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info, - char *args ) + +static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r, + char *args) { char *str, *str2; - uint32 len, i; + int count = 0; char *saveptr = NULL; + struct spoolss_StringArray *deps; + const char **file_array = NULL; + int i; /* fill in the UNISTR fields */ - str = get_driver_3_param (args, ":", &info->name, &saveptr); - str = get_driver_3_param (NULL, ":", &info->driverpath, &saveptr); - str = get_driver_3_param (NULL, ":", &info->datafile, &saveptr); - str = get_driver_3_param (NULL, ":", &info->configfile, &saveptr); - str = get_driver_3_param (NULL, ":", &info->helpfile, &saveptr); - str = get_driver_3_param (NULL, ":", &info->monitorname, &saveptr); - str = get_driver_3_param (NULL, ":", &info->defaultdatatype, &saveptr); + str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr); /* */ /* save the beginning of the string */ - str2 = get_driver_3_param (NULL, ":", NULL, &saveptr); + str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr); str = str2; /* begin to strip out each filename */ str = strtok_r(str, ",", &saveptr); - len = 0; - while (str != NULL) - { - /* keep a cumlative count of the str lengths */ - len += strlen(str)+1; + + /* no dependent files, we are done */ + if (!str) { + return true; + } + + deps = talloc_zero(mem_ctx, struct spoolss_StringArray); + if (!deps) { + return false; + } + + while (str != NULL) { + add_string_to_array(deps, str, &file_array, &count); str = strtok_r(NULL, ",", &saveptr); } - /* allocate the space; add one extra slot for a terminating NULL. - Each filename is NULL terminated and the end contains a double - NULL */ - if ((info->dependentfiles=TALLOC_ARRAY(mem_ctx, uint16, len+1)) == NULL) - { - DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n")); - return False; + deps->string = talloc_zero_array(deps, const char *, count + 1); + if (!deps->string) { + return false; } - for (i=0; idependentfiles[i], 0, str2[i]); + + for (i=0; i < count; i++) { + deps->string[i] = file_array[i]; } - info->dependentfiles[len] = '\0'; - return True; -} + r->dependent_files = deps; + return true; +} /**************************************************************************** ****************************************************************************/ @@ -1403,11 +1416,11 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli, int argc, const char **argv) { WERROR result; + NTSTATUS status; uint32 level = 3; - PRINTER_DRIVER_CTR ctr; - DRIVER_INFO_3 info3; + struct spoolss_AddDriverInfoCtr info_ctr; + struct spoolss_AddDriverInfo3 info3; const char *arch; - fstring driver_name; char *driver_args; /* parse the command arguments */ @@ -1422,15 +1435,16 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli, return WERR_OK; } - /* Fill in the DRIVER_INFO_3 struct */ + /* Fill in the spoolss_AddDriverInfo3 struct */ ZERO_STRUCT(info3); - if (!(arch = cmd_spoolss_get_short_archi(argv[1]))) - { + + arch = cmd_spoolss_get_short_archi(argv[1]); + if (!arch) { printf ("Error Unknown architechture [%s]\n", argv[1]); return WERR_INVALID_PARAM; } - else - set_drv_info_3_env(&info3, arch); + + set_drv_info_3_env(mem_ctx, &info3, arch); driver_args = talloc_strdup( mem_ctx, argv[2] ); if (!init_drv_info_3_members(mem_ctx, &info3, driver_args )) @@ -1448,14 +1462,19 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli, } - ctr.info3 = &info3; - result = rpccli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr); + info_ctr.level = level; + info_ctr.info.info3 = &info3; + status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx, + cli->srv_name_slash, + &info_ctr, + &result); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } if (W_ERROR_IS_OK(result)) { - rpcstr_pull(driver_name, info3.name.buffer, - sizeof(driver_name), -1, STR_TERMINATE); printf ("Printer Driver %s successfully installed.\n", - driver_name); + info3.driver_name); } return result; -- cgit From b2e038ef8bd78e9ca847bbd0aaaf593cea059b18 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:53:05 +0100 Subject: s3-spoolss: remove rpccli_spoolss_addprinterdriver. Guenther --- source3/include/proto.h | 6 --- source3/rpc_client/cli_spoolss.c | 30 ----------- source3/rpc_parse/parse_spoolss.c | 103 -------------------------------------- 3 files changed, 139 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 95c4c1659b..6edad71a99 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5492,9 +5492,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, uint32 level, const char *env, uint32 *num_drivers, PRINTER_DRIVER_CTR *ctr); -WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr); WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, PRINTER_INFO_CTR*ctr); WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, @@ -5941,9 +5938,6 @@ bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_I bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, uint32 level, PRINTER_DRIVER_CTR *info); -bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info, - DRIVER_INFO_3 *info3); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 8a8dabeba4..19e9aae0f8 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -886,36 +886,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTERDRIVER in; - SPOOL_R_ADDPRINTERDRIVER out; - fstring server; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper_m(server); - - make_spoolss_q_addprinterdriver( mem_ctx, &in, server, level, ctr ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTERDRIVER, - in, out, - qbuf, rbuf, - spoolss_io_q_addprinterdriver, - spoolss_io_r_addprinterdriver, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, PRINTER_INFO_CTR*ctr) { diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 4ffa121e1c..9c69dd2659 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -3382,109 +3382,6 @@ bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_I return True; } -/******************************************************************* - init a SPOOL_Q_ADDPRINTERDRIVER struct - ******************************************************************/ - -bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx, - SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, - uint32 level, PRINTER_DRIVER_CTR *info) -{ - DEBUG(5,("make_spoolss_q_addprinterdriver\n")); - - if (!srv_name || !info) { - return False; - } - - q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */ - init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE); - - q_u->level = level; - - q_u->info.level = level; - q_u->info.ptr = 1; /* Info is != NULL, see above */ - switch (level) - { - /* info level 3 is supported by Windows 95/98, WinNT and Win2k */ - case 3 : - make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3); - break; - - default: - DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level)); - break; - } - - return True; -} - -bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info, - DRIVER_INFO_3 *info3) -{ - uint32 len = 0; - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf; - - if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3))) - return False; - - inf->cversion = info3->version; - inf->name_ptr = (info3->name.buffer!=NULL)?1:0; - inf->environment_ptr = (info3->architecture.buffer!=NULL)?1:0; - inf->driverpath_ptr = (info3->driverpath.buffer!=NULL)?1:0; - inf->datafile_ptr = (info3->datafile.buffer!=NULL)?1:0; - inf->configfile_ptr = (info3->configfile.buffer!=NULL)?1:0; - inf->helpfile_ptr = (info3->helpfile.buffer!=NULL)?1:0; - inf->monitorname_ptr = (info3->monitorname.buffer!=NULL)?1:0; - inf->defaultdatatype_ptr = (info3->defaultdatatype.buffer!=NULL)?1:0; - - init_unistr2_from_unistr(inf, &inf->name, &info3->name); - init_unistr2_from_unistr(inf, &inf->environment, &info3->architecture); - init_unistr2_from_unistr(inf, &inf->driverpath, &info3->driverpath); - init_unistr2_from_unistr(inf, &inf->datafile, &info3->datafile); - init_unistr2_from_unistr(inf, &inf->configfile, &info3->configfile); - init_unistr2_from_unistr(inf, &inf->helpfile, &info3->helpfile); - init_unistr2_from_unistr(inf, &inf->monitorname, &info3->monitorname); - init_unistr2_from_unistr(inf, &inf->defaultdatatype, &info3->defaultdatatype); - - if (info3->dependentfiles) { - bool done = False; - bool null_char = False; - uint16 *ptr = info3->dependentfiles; - - while (!done) { - switch (*ptr) { - case 0: - /* the null_char bool is used to help locate - two '\0's back to back */ - if (null_char) { - done = True; - } else { - null_char = True; - } - break; - - default: - null_char = False; - break; - } - len++; - ptr++; - } - } - - inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0; - inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0; - if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) { - SAFE_FREE(inf); - return False; - } - - *spool_drv_info = inf; - - return True; -} - /******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ -- cgit From 28fb708ba0bf3c81e54b1f99a8f56d671e62a047 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 23:45:14 +0100 Subject: error-codes: print out WERR_UNKNOWN_PRINT_MONITOR. Guenther --- libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libcli/util/doserr.c b/libcli/util/doserr.c index 226c2f950d..1044ab351a 100644 --- a/libcli/util/doserr.c +++ b/libcli/util/doserr.c @@ -169,6 +169,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_SERVICE_NEVER_STARTED", WERR_SERVICE_NEVER_STARTED }, { "WERR_PASSWORD_MUST_CHANGE", WERR_PASSWORD_MUST_CHANGE }, { "WERR_ACCOUNT_LOCKED_OUT", WERR_ACCOUNT_LOCKED_OUT }, + { "WERR_UNKNOWN_PRINT_MONITOR", WERR_UNKNOWN_PRINT_MONITOR }, { NULL, W_ERROR(0) } }; -- cgit From a028e9640b54554f4ae036f46cc16ae73f00884e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 15:27:47 -0800 Subject: Make S4 build on OpenSolaris. Jeremy. --- source4/lib/tls/config.m4 | 2 ++ source4/lib/tls/config.mk | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/lib/tls/config.m4 b/source4/lib/tls/config.m4 index 0bafc5ddf1..c46a009e3d 100644 --- a/source4/lib/tls/config.m4 +++ b/source4/lib/tls/config.m4 @@ -40,4 +40,6 @@ if test x$use_gnutls = xyes; then AC_CHECK_TYPES([gnutls_datum_t],,,[#include "gnutls/gnutls.h"]) AC_DEFINE(ENABLE_GNUTLS,1,[Whether we have gnutls support (SSL)]) AC_CHECK_HEADERS(gcrypt.h) + AC_CHECK_LIB_EXT(gcrypt, GCRYPT_LIBS, gcry_control) + SMB_EXT_LIB(GCRYPT, $GCRYPT_LIBS) fi diff --git a/source4/lib/tls/config.mk b/source4/lib/tls/config.mk index ff1eedfd5d..0e1978cc1b 100644 --- a/source4/lib/tls/config.mk +++ b/source4/lib/tls/config.mk @@ -1,5 +1,5 @@ [SUBSYSTEM::LIBTLS] PUBLIC_DEPENDENCIES = \ - LIBTALLOC GNUTLS LIBSAMBA-HOSTCONFIG samba_socket + LIBTALLOC GNUTLS GCRYPT LIBSAMBA-HOSTCONFIG samba_socket LIBTLS_OBJ_FILES = $(addprefix $(libtlssrcdir)/, tls.o tlscert.o) -- cgit From b3d53e2ce6da661c3b41f03fdb0ecbe44579b593 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 00:30:14 +0100 Subject: s3-spoolss: remove some left-over hand marshalling code and structs. Guenther --- source3/include/proto.h | 16 -- source3/include/rpc_spoolss.h | 93 ----------- source3/rpc_parse/parse_spoolss.c | 324 -------------------------------------- 3 files changed, 433 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 6edad71a99..9366607995 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5867,11 +5867,6 @@ uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info); uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p); uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info); uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info); -bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, - const POLICY_HND *hnd, - const fstring architecture, - uint32 level, uint32 clientmajor, uint32 clientminor, - RPC_BUFFER *buffer, uint32 offered); bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth); bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth); bool make_spoolss_q_enumprinters( @@ -5929,18 +5924,7 @@ bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth); bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth); -bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, - prs_struct *ps, int depth); -bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, - prs_struct *ps, int depth); -bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth); -bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth); -bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx, - SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, - uint32 level, PRINTER_DRIVER_CTR *info); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); -bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, NT_PRINTER_INFO_LEVEL_2 *d); bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 504cfea70b..48609a3cd6 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -945,82 +945,6 @@ typedef struct spool_printer_info_level } SPOOL_PRINTER_INFO_LEVEL; -typedef struct spool_printer_driver_info_level_3 -{ - uint32 cversion; - uint32 name_ptr; - uint32 environment_ptr; - uint32 driverpath_ptr; - uint32 datafile_ptr; - uint32 configfile_ptr; - uint32 helpfile_ptr; - uint32 monitorname_ptr; - uint32 defaultdatatype_ptr; - uint32 dependentfilessize; - uint32 dependentfiles_ptr; - - UNISTR2 name; - UNISTR2 environment; - UNISTR2 driverpath; - UNISTR2 datafile; - UNISTR2 configfile; - UNISTR2 helpfile; - UNISTR2 monitorname; - UNISTR2 defaultdatatype; - BUFFER5 dependentfiles; - -} -SPOOL_PRINTER_DRIVER_INFO_LEVEL_3; - -/* SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure */ -typedef struct { - uint32 version; - uint32 name_ptr; - uint32 environment_ptr; - uint32 driverpath_ptr; - uint32 datafile_ptr; - uint32 configfile_ptr; - uint32 helpfile_ptr; - uint32 monitorname_ptr; - uint32 defaultdatatype_ptr; - uint32 dependentfiles_len; - uint32 dependentfiles_ptr; - uint32 previousnames_len; - uint32 previousnames_ptr; - NTTIME driverdate; - uint64 driverversion; - uint32 dummy4; - uint32 mfgname_ptr; - uint32 oemurl_ptr; - uint32 hardwareid_ptr; - uint32 provider_ptr; - UNISTR2 name; - UNISTR2 environment; - UNISTR2 driverpath; - UNISTR2 datafile; - UNISTR2 configfile; - UNISTR2 helpfile; - UNISTR2 monitorname; - UNISTR2 defaultdatatype; - BUFFER5 dependentfiles; - BUFFER5 previousnames; - UNISTR2 mfgname; - UNISTR2 oemurl; - UNISTR2 hardwareid; - UNISTR2 provider; -} SPOOL_PRINTER_DRIVER_INFO_LEVEL_6; - - -typedef struct spool_printer_driver_info_level -{ - uint32 level; - uint32 ptr; - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *info_3; - SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *info_6; -} -SPOOL_PRINTER_DRIVER_INFO_LEVEL; - - typedef struct spool_q_setprinter { POLICY_HND handle; @@ -1057,23 +981,6 @@ typedef struct { WERROR status; } SPOOL_R_ADDPRINTEREX; -/********************************************/ - -typedef struct spool_q_addprinterdriver -{ - uint32 server_name_ptr; - UNISTR2 server_name; - uint32 level; - SPOOL_PRINTER_DRIVER_INFO_LEVEL info; -} -SPOOL_Q_ADDPRINTERDRIVER; - -typedef struct spool_r_addprinterdriver -{ - WERROR status; -} -SPOOL_R_ADDPRINTERDRIVER; - typedef struct spool_q_enumprintprocessors { uint32 name_ptr; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 9c69dd2659..12c7af49cf 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -3100,288 +3100,6 @@ bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, return True; } -/******************************************************************* -********************************************************************/ - -bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, - prs_struct *ps, int depth) -{ - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il; - - prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3"); - depth++; - - /* reading */ - if (UNMARSHALLING(ps)) { - il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1); - if(il == NULL) - return False; - *q_u=il; - } - else { - il=*q_u; - } - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("cversion", ps, depth, &il->cversion)) - return False; - if(!prs_uint32("name", ps, depth, &il->name_ptr)) - return False; - if(!prs_uint32("environment", ps, depth, &il->environment_ptr)) - return False; - if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr)) - return False; - if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr)) - return False; - if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr)) - return False; - if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr)) - return False; - if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr)) - return False; - if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr)) - return False; - if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize)) - return False; - if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr)) - return False; - - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if (il->dependentfiles_ptr) - smb_io_buffer5("", &il->dependentfiles, ps, depth); - - return True; -} - -/******************************************************************* -parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure -********************************************************************/ - -bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, - prs_struct *ps, int depth) -{ - SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il; - - prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6"); - depth++; - - /* reading */ - if (UNMARSHALLING(ps)) { - il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1); - if(il == NULL) - return False; - *q_u=il; - } - else { - il=*q_u; - } - - if(!prs_align(ps)) - return False; - - /* - * I know this seems weird, but I have no other explanation. - * This is observed behavior on both NT4 and 2K servers. - * --jerry - */ - - if (!prs_align_uint64(ps)) - return False; - - /* parse the main elements the packet */ - - if(!prs_uint32("cversion ", ps, depth, &il->version)) - return False; - if(!prs_uint32("name ", ps, depth, &il->name_ptr)) - return False; - if(!prs_uint32("environment ", ps, depth, &il->environment_ptr)) - return False; - if(!prs_uint32("driverpath ", ps, depth, &il->driverpath_ptr)) - return False; - if(!prs_uint32("datafile ", ps, depth, &il->datafile_ptr)) - return False; - if(!prs_uint32("configfile ", ps, depth, &il->configfile_ptr)) - return False; - if(!prs_uint32("helpfile ", ps, depth, &il->helpfile_ptr)) - return False; - if(!prs_uint32("monitorname ", ps, depth, &il->monitorname_ptr)) - return False; - if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr)) - return False; - if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len)) - return False; - if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr)) - return False; - if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_len)) - return False; - if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_ptr)) - return False; - if(!smb_io_time("driverdate ", &il->driverdate, ps, depth)) - return False; - if(!prs_uint32("dummy4 ", ps, depth, &il->dummy4)) - return False; - if(!prs_uint64("driverversion ", ps, depth, &il->driverversion)) - return False; - if(!prs_uint32("mfgname ", ps, depth, &il->mfgname_ptr)) - return False; - if(!prs_uint32("oemurl ", ps, depth, &il->oemurl_ptr)) - return False; - if(!prs_uint32("hardwareid ", ps, depth, &il->hardwareid_ptr)) - return False; - if(!prs_uint32("provider ", ps, depth, &il->provider_ptr)) - return False; - - /* parse the structures in the packet */ - - if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if (il->dependentfiles_ptr) { - if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - } - if (il->previousnames_ptr) { - if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - } - if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - read a UNICODE array with null terminated strings - and null terminated array - and size of array at beginning -********************************************************************/ - -bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth) -{ - if (buffer==NULL) return False; - - buffer->offset=0; - buffer->uni_str_len=buffer->uni_max_len; - - if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len)) - return False; - - if(!prs_unistr2(True, "buffer ", ps, depth, buffer)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("level", ps, depth, &il->level)) - return False; - if(!prs_uint32("ptr", ps, depth, &il->ptr)) - return False; - - if (il->ptr==0) - return True; - - switch (il->level) { - case 3: - if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth)) - return False; - break; - case 6: - if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth)) - return False; - break; - default: - return False; - } - - return True; -} - /******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ @@ -3406,48 +3124,6 @@ bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 return True; } -/******************************************************************* - fill in the prs_struct for a ADDPRINTERDRIVER request PDU - ********************************************************************/ - -bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr)) - return False; - if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("info_level", ps, depth, &q_u->level)) - return False; - - if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver"); - depth++; - - if(!prs_werror("status", ps, depth, &q_u->status)) - return False; - - return True; -} - /******************************************************************* ********************************************************************/ -- cgit From 503d15e8df9075ea9cf8b2d260487e68fc68f559 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Wed, 25 Feb 2009 10:27:19 +1100 Subject: Updates to the recent cn=config support for the OpenLDAP backend - removed workaround for olcSyncprovConfig - creation (works perfect now with 2.4.15, release was today) - added 1 message-helpline, which is displayed when running provision-backend with olc and/or mmr setup - corrected 1 wrong slapcommand-helpline - slapd.conf is removed now in case of olc-setup - added 1 copyright-line to provision.py and provision-backend Signed-off-by: Andrew Bartlett --- source4/scripting/python/samba/provision.py | 24 ++++++------------------ source4/setup/olcOverlay={0}syncprov.ldif | 11 ----------- source4/setup/provision-backend | 5 +++-- 3 files changed, 9 insertions(+), 31 deletions(-) delete mode 100644 source4/setup/olcOverlay={0}syncprov.ldif diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8442c24d71..c817bffbdd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -4,6 +4,7 @@ # Copyright (C) Jelmer Vernooij 2007-2008 # Copyright (C) Andrew Bartlett 2008 +# Copyright (C) Oliver Liebel 2008-2009 # # Based on the original in EJS: # Copyright (C) Andrew Tridgell 2005 @@ -100,8 +101,6 @@ class ProvisionPaths(object): self.olcdir = None self.olslaptest = None self.olcseedldif = None - self.olcsyncprovdir = None - self.olcsyncprovfile = None class ProvisionNames(object): @@ -278,10 +277,6 @@ def provision_paths_from_lp(lp, dnsdomain): "slapd.d") paths.olcseedldif = os.path.join(paths.ldapdir, "olc_seed.ldif") - paths.olcsyncprovdir = os.path.join(paths.olcdir, - "cn=config/olcDatabase={0}config") - paths.olcsyncprovfile = os.path.join(paths.olcsyncprovdir, - "olcOverlay={0}syncprov.ldif") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -1479,7 +1474,7 @@ def provision_backend(setup_dir=None, message=None, slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" if ol_olc != "yes" and ol_mmr_urls is not None: - slapdcommand="Start slapd with: slapd -F " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" if ol_olc == "yes" and ol_mmr_urls is not None: slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" @@ -1505,6 +1500,8 @@ def provision_backend(setup_dir=None, message=None, message("LDAP admin password: %s" % adminpass) message(slapdcommand) + if ol_olc == "yes" or ol_mmr_urls is not None: + message("Attention to slapd-Port: must be different than 389!") assert isinstance(ldap_backend_type, str) assert isinstance(ldapuser, str) assert isinstance(adminpass, str) @@ -1528,19 +1525,10 @@ def provision_backend(setup_dir=None, message=None, paths.olslaptest = str(ol_slaptest) olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir + " >/dev/null 2>&1" os.system(olc_command) - #os.remove(paths.slapdconf) - # use line below for debugging during olc-conversion with slaptest + os.remove(paths.slapdconf) + # use line below for debugging during olc-conversion with slaptest, instead of olc_command above #olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir" - # workaround, if overlay syncprov is was not created properly during conversion to cn=config. - # otherwise, cn=config won't be replicated - if ol_olc == "yes" and ol_mmr_urls is not None: - if not os.path.exists(paths.olcsyncprovdir): - os.makedirs(paths.olcsyncprovdir, 0770) - setup_file(setup_path("olcOverlay={0}syncprov.ldif"), - os.path.join(paths.olcsyncprovdir, "olcOverlay={0}syncprov.ldif"), {}) - - def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. diff --git a/source4/setup/olcOverlay={0}syncprov.ldif b/source4/setup/olcOverlay={0}syncprov.ldif deleted file mode 100644 index 4f5b513c67..0000000000 --- a/source4/setup/olcOverlay={0}syncprov.ldif +++ /dev/null @@ -1,11 +0,0 @@ -dn: olcOverlay={0}syncprov -objectClass: olcOverlayConfig -objectClass: olcSyncProvConfig -olcOverlay: {0}syncprov -structuralObjectClass: olcSyncProvConfig -entryUUID: 41df5aca-785a-102d-9077-999999999999 -creatorsName: cn=config -createTimestamp: 20090116201111Z -entryCSN: 20090116201111.111111Z#000000#000#000000 -modifiersName: cn=config -modifyTimestamp: 20090116201111Z diff --git a/source4/setup/provision-backend b/source4/setup/provision-backend index 20e4420414..28e73ae302 100755 --- a/source4/setup/provision-backend +++ b/source4/setup/provision-backend @@ -4,6 +4,7 @@ # provision a Samba4 server # Copyright (C) Jelmer Vernooij 2007-2008 # Copyright (C) Andrew Bartlett 2008 +# Copyright (C) Oliver Liebel 2008-2009 # # Based on the original in EJS: # Copyright (C) Andrew Tridgell 2005 @@ -65,9 +66,9 @@ parser.add_option("--server-role", type="choice", metavar="ROLE", parser.add_option("--targetdir", type="string", metavar="DIR", help="Set target directory") parser.add_option("--ol-mmr-urls", type="string", metavar="LDAPSERVER", - help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") + help="List of LDAP-URLS [ ldap://:/ (where has to be different from 389!) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") parser.add_option("--ol-olc", type="choice", metavar="OPENLDAP-OLC", - help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'", + help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'. Note: Only OpenLDAP-Versions greater or equal 2.4.15 should be used!", choices=["yes", "no"]) parser.add_option("--ol-slaptest", type="string", metavar="SLAPTEST-PATH", help="Path to slaptest-binary [e.g.:'/usr/local/sbin']. Only for use with --ol-olc='yes'") -- cgit From 95bf60b39d003bea6f9f5ad2bc63d5f2a8b8b2af Mon Sep 17 00:00:00 2001 From: todd stecher Date: Mon, 23 Feb 2009 10:24:33 -0800 Subject: S3: Add in profile counters for new vfs and syscall entries. --- source3/include/smbprofile.h | 28 ++++++++++++++++++++++++++++ source3/modules/onefs_acl.c | 11 ++++++++++- source3/modules/onefs_cbrl.c | 26 ++++++++++++++++++++++++-- source3/modules/onefs_streams.c | 16 +++++++++++++--- source3/modules/onefs_system.c | 18 ++++++++++++++++++ source3/profile/profile.c | 7 +++++++ 6 files changed, 100 insertions(+), 6 deletions(-) diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 131416b685..f9a0436546 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -75,6 +75,10 @@ enum profile_stats_values #define syscall_open_count __profile_stats_value(PR_VALUE_SYSCALL_OPEN, count) #define syscall_open_time __profile_stats_value(PR_VALUE_SYSCALL_OPEN, time) + PR_VALUE_SYSCALL_CREATEFILE, +#define syscall_createfile_count __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, count) +#define syscall_createfile_time __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, time) + PR_VALUE_SYSCALL_CLOSE, #define syscall_close_count __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, count) #define syscall_close_time __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, time) @@ -111,6 +115,10 @@ enum profile_stats_values #define syscall_rename_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME, count) #define syscall_rename_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME, time) + PR_VALUE_SYSCALL_RENAME_AT, +#define syscall_rename_at_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, count) +#define syscall_rename_at_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, time) + PR_VALUE_SYSCALL_FSYNC, #define syscall_fsync_count __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, count) #define syscall_fsync_time __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, time) @@ -215,6 +223,26 @@ enum profile_stats_values #define syscall_set_quota_count __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, count) #define syscall_set_quota_time __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, time) + PR_VALUE_SYSCALL_GET_SD, +#define syscall_get_sd_count __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, count) +#define syscall_get_sd_time __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, time) + + PR_VALUE_SYSCALL_SET_SD, +#define syscall_set_sd_count __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, count) +#define syscall_set_sd_time __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, time) + + PR_VALUE_SYSCALL_BRL_LOCK, +#define syscall_brl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, count) +#define syscall_brl_lock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, time) + + PR_VALUE_SYSCALL_BRL_UNLOCK, +#define syscall_brl_unlock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, count) +#define syscall_brl_unlock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, time) + + PR_VALUE_SYSCALL_BRL_CANCEL, +#define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count) +#define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time) + /* counters for individual SMB types */ PR_VALUE_SMBMKDIR, #define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 7bc4a1728f..b463722e61 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -614,6 +614,8 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, bool fopened = false; NTSTATUS status = NT_STATUS_OK; + START_PROFILE(syscall_get_sd); + *ppdesc = NULL; DEBUG(5, ("Getting sd for file %s. security_info=%u\n", @@ -753,6 +755,9 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, DEBUG(5, ("Finished retrieving/canonicalizing SD!\n")); /* FALLTHROUGH */ out: + + END_PROFILE(syscall_get_sd); + if (alloced && sd) { if (new_aces_alloced && sd->dacl->aces) SAFE_FREE(sd->dacl->aces); @@ -892,6 +897,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, bool fopened = false; NTSTATUS status; + START_PROFILE(syscall_set_sd); + DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name )); status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd, @@ -899,7 +906,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); - return status; + goto out; } fd = fsp->fh->fd; @@ -938,6 +945,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, /* FALLTHROUGH */ out: + END_PROFILE(syscall_set_sd); + if (fopened) close(fd); diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c index a860023764..2c5e39c359 100644 --- a/source3/modules/onefs_cbrl.c +++ b/source3/modules/onefs_cbrl.c @@ -255,6 +255,8 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, struct onefs_cbrl_blr_state *bs; NTSTATUS status; + START_PROFILE(syscall_brl_lock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); @@ -301,10 +303,13 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, /* ASYNC still in progress: The process_* calls will keep * calling even if we haven't gotten the lock. Keep erroring * without calling ifs_cbrl, or getting/setting an id. */ - if (bs->state == ONEFS_CBRL_ASYNC) + if (bs->state == ONEFS_CBRL_ASYNC) { goto failure; - else if (bs->state == ONEFS_CBRL_ERROR) + } + else if (bs->state == ONEFS_CBRL_ERROR) { + END_PROFILE(syscall_brl_lock); return NT_STATUS_NO_MEMORY; + } SMB_ASSERT(bs->state == ONEFS_CBRL_NONE); async = true; @@ -343,6 +348,9 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, } failure: + + END_PROFILE(syscall_brl_lock); + /* Failure - error or async. */ plock->context.smbpid = (uint32) ONEFS_BLOCKING_PID; @@ -355,6 +363,9 @@ failure: return status; success: + + END_PROFILE(syscall_brl_lock); + /* Success. */ onefs_cbrl_enumerate_blq("onefs_brl_unlock_windows"); DEBUG(10, ("returning NT_STATUS_OK.\n")); @@ -371,6 +382,8 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, int error; int fd = br_lck->fsp->fh->fd; + START_PROFILE(syscall_brl_unlock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type == UNLOCK_LOCK); @@ -378,6 +391,9 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_unlock); + if (error) { DEBUG(10, ("returning false.\n")); return false; @@ -404,6 +420,8 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, int fd = br_lck->fsp->fh->fd; struct onefs_cbrl_blr_state *bs; + START_PROFILE(syscall_brl_cancel); + SMB_ASSERT(plock); SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(blr); @@ -416,6 +434,7 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, if (bs->state == ONEFS_CBRL_DONE) { /* No-op. */ DEBUG(10, ("State=DONE, returning true\n")); + END_PROFILE(syscall_brl_cancel); return true; } @@ -427,6 +446,9 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_cancel); + if (error) { DEBUG(10, ("returning false\n")); bs->state = ONEFS_CBRL_ERROR; diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 9616ca48d5..2dcd8891eb 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -160,18 +160,26 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, char *nbase = NULL; char *nsname = NULL; + START_PROFILE(syscall_rename_at); + frame = talloc_stackframe(); ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } if (!old_is_stream && !new_is_stream) { - return SMB_VFS_NEXT_RENAME(handle, oldname, newname); + ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname); + END_PROFILE(syscall_rename_at); + return ret; } dir_fd = get_stream_dir_fd(handle->conn, obase, NULL); @@ -192,6 +200,8 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, } done: + END_PROFILE(syscall_rename_at); + saved_errno = errno; if (dir_fd >= 0) { close(dir_fd); diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 76df006d82..518a398154 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -95,6 +95,8 @@ int onefs_sys_create_file(connection_struct *conn, uint32_t onefs_dos_attributes; struct ifs_createfile_flags cf_flags = CF_FLAGS_NONE; + START_PROFILE(syscall_createfile); + /* Setup security descriptor and get secinfo. */ if (sd != NULL) { NTSTATUS status; @@ -196,6 +198,7 @@ int onefs_sys_create_file(connection_struct *conn, } out: + END_PROFILE(syscall_createfile); aclu_free_sd(pifs_sd, false); return ret_fd; @@ -307,6 +310,8 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, bool atomic = false; ssize_t ret = 0; + START_PROFILE_BYTES(syscall_sendfile, count); + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_ATOMIC_SENDFILE, PARM_ATOMIC_SENDFILE_DEFAULT)) { @@ -320,6 +325,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* If the sendfile wasn't atomic, we're done. */ if (!atomic) { DEBUG(10, ("non-atomic sendfile read %ul bytes", ret)); + END_PROFILE(syscall_sendfile); return ret; } @@ -391,6 +397,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* Handle case 1: short read -> truncated file. */ if (ret == 0) { + END_PROFILE(syscall_sendfile); return ret; } @@ -402,6 +409,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, PARM_SENDFILE_LARGE_READS_DEFAULT)) { DEBUG(3, ("Not attempting non-atomic large sendfile: " "%lu bytes\n", count)); + END_PROFILE(syscall_sendfile); return 0; } @@ -421,6 +429,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, DEBUG(1, ("error on non-atomic large sendfile " "(%lu bytes): %s\n", count, strerror(errno))); + END_PROFILE(syscall_sendfile); return ret; } @@ -439,9 +448,11 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_SENDFILE_SAFE, PARM_SENDFILE_SAFE_DEFAULT)) { + END_PROFILE(syscall_sendfile); return -1; } + END_PROFILE(syscall_sendfile); return ret; } @@ -455,6 +466,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, count, strerror(errno))); } + END_PROFILE(syscall_sendfile); return ret; } @@ -509,10 +521,13 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, off_t rbytes; off_t wbytes; + START_PROFILE_BYTES(syscall_recvfile, count); + DEBUG(10,("onefs_recvfile: from = %d, to = %d, offset=%llu, count = " "%lu\n", fromfd, tofd, offset, count)); if (count == 0) { + END_PROFILE(syscall_recvfile); return 0; } @@ -624,6 +639,9 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, ret = total_wbytes; out: + + END_PROFILE(syscall_recvfile); + /* Make sure we always try to drain the socket. */ if (!socket_drained && count - total_rbytes) { int saved_errno = errno; diff --git a/source3/profile/profile.c b/source3/profile/profile.c index bdbd805718..6d2d5ae06d 100644 --- a/source3/profile/profile.c +++ b/source3/profile/profile.c @@ -290,6 +290,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_rmdir", /* PR_VALUE_SYSCALL_RMDIR */ "syscall_closedir", /* PR_VALUE_SYSCALL_CLOSEDIR */ "syscall_open", /* PR_VALUE_SYSCALL_OPEN */ + "syscall_createfile", /* PR_VALUE_SYSCALL_CREATEFILE */ "syscall_close", /* PR_VALUE_SYSCALL_CLOSE */ "syscall_read", /* PR_VALUE_SYSCALL_READ */ "syscall_pread", /* PR_VALUE_SYSCALL_PREAD */ @@ -299,6 +300,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_sendfile", /* PR_VALUE_SYSCALL_SENDFILE */ "syscall_recvfile", /* PR_VALUE_SYSCALL_RECVFILE */ "syscall_rename", /* PR_VALUE_SYSCALL_RENAME */ + "syscall_rename_at", /* PR_VALUE_SYSCALL_RENAME_AT */ "syscall_fsync", /* PR_VALUE_SYSCALL_FSYNC */ "syscall_stat", /* PR_VALUE_SYSCALL_STAT */ "syscall_fstat", /* PR_VALUE_SYSCALL_FSTAT */ @@ -323,6 +325,11 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_realpath", /* PR_VALUE_SYSCALL_REALPATH */ "syscall_get_quota", /* PR_VALUE_SYSCALL_GET_QUOTA */ "syscall_set_quota", /* PR_VALUE_SYSCALL_SET_QUOTA */ + "syscall_get_sd", /* PR_VALUE_SYSCALL_GET_SD */ + "syscall_set_sd", /* PR_VALUE_SYSCALL_SET_SD */ + "syscall_brl_lock", /* PR_VALUE_SYSCALL_BRL_LOCK */ + "syscall_brl_unlock", /* PR_VALUE_SYSCALL_BRL_UNLOCK */ + "syscall_brl_cancel", /* PR_VALUE_SYSCALL_BRL_CANCEL */ "SMBmkdir", /* PR_VALUE_SMBMKDIR */ "SMBrmdir", /* PR_VALUE_SMBRMDIR */ "SMBopen", /* PR_VALUE_SMBOPEN */ -- cgit From 4e024b3f87ee1ccb0d7c83dfc6a4b5a6b2c47c13 Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Tue, 24 Feb 2009 14:12:48 -0800 Subject: s3: onefs_acl.c cleanup Remove some duplicate code. Add a \n to a debugging statement --- source3/modules/onefs_acl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index b463722e61..b8097b6455 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -273,9 +273,6 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl, if (aclu_initialize_acl(acl, aces, num_aces)) goto err_free; - if (aclu_initialize_acl(acl, aces, num_aces)) - goto err_free; - /* Currently aclu_initialize_acl should copy the aces over, allowing * us to immediately free */ free(aces); @@ -905,7 +902,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, SNUM(handle->conn)); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); + DEBUG(3, ("SD initialization failure: %s\n", nt_errstr(status))); goto out; } -- cgit From aeab22b55cb1484ff6da7242bd525e30b69e5752 Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Mon, 23 Feb 2009 23:21:13 -0800 Subject: s3: Rename auth_onefs_wb and pdb_onefs_sam auth_onefs_wb.c -> auth_wbc.c pdb_onefs_sam.c -> pdb_wbc_sam.c No changes to functionality --- source3/Makefile.in | 10 +- source3/auth/auth_onefs_wb.c | 134 ------------ source3/auth/auth_wbc.c | 150 ++++++++++++++ source3/configure.in | 8 +- source3/passdb/pdb_onefs_sam.c | 433 --------------------------------------- source3/passdb/pdb_wbc_sam.c | 448 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 607 insertions(+), 576 deletions(-) delete mode 100644 source3/auth/auth_onefs_wb.c create mode 100644 source3/auth/auth_wbc.c delete mode 100644 source3/passdb/pdb_onefs_sam.c create mode 100644 source3/passdb/pdb_wbc_sam.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 73b2989421..8f1d1a5b77 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -689,7 +689,7 @@ AUTH_SAM_OBJ = auth/auth_sam.o AUTH_SERVER_OBJ = auth/auth_server.o AUTH_UNIX_OBJ = auth/auth_unix.o AUTH_WINBIND_OBJ = auth/auth_winbind.o -AUTH_ONEFS_WB_OBJ = auth/auth_onefs_wb.o +AUTH_WBC_OBJ = auth/auth_wbc.o AUTH_SCRIPT_OBJ = auth/auth_script.o AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o @@ -2355,9 +2355,9 @@ bin/winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WINBIND_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(AUTH_WINBIND_OBJ) -bin/onefs_wb.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_ONEFS_WB_OBJ) +bin/wbc.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WBC_OBJ) @echo "Building plugin $@" - @$(SHLD_MODULE) $(AUTH_ONEFS_WB_OBJ) + @$(SHLD_MODULE) $(AUTH_WBC_OBJ) bin/unix.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_UNIX_OBJ) @echo "Building plugin $@" @@ -2375,9 +2375,9 @@ bin/tdbsam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_tdb.o @echo "Building plugin $@" @$(SHLD_MODULE) passdb/pdb_tdb.o -bin/onefs_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_onefs_sam.o +bin/wbc_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_wbc_sam.o @echo "Building plugin $@" - @$(SHLD_MODULE) passdb/pdb_onefs_sam.o + @$(SHLD_MODULE) passdb/pdb_wbc_sam.o bin/smbpasswd.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_smbpasswd.o @echo "Building plugin $@" diff --git a/source3/auth/auth_onefs_wb.c b/source3/auth/auth_onefs_wb.c deleted file mode 100644 index 49de6966b0..0000000000 --- a/source3/auth/auth_onefs_wb.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind authentication mechnism, customized for onefs - - Copyright (C) Tim Potter 2000 - Copyright (C) Andrew Bartlett 2001 - 2002 - Copyright (C) Dan Sledz 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -/* Authenticate a user with a challenge/response */ - -static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context, - void *my_private_data, - TALLOC_CTX *mem_ctx, - const auth_usersupplied_info *user_info, - auth_serversupplied_info **server_info) -{ - NTSTATUS nt_status; - wbcErr wbc_status; - struct wbcAuthUserParams params; - struct wbcAuthUserInfo *info = NULL; - struct wbcAuthErrorInfo *err = NULL; - - if (!user_info || !auth_context || !server_info) { - return NT_STATUS_INVALID_PARAMETER; - } - /* Send off request */ - - params.account_name = user_info->smb_name; - params.domain_name = user_info->domain; - params.workstation_name = user_info->wksta_name; - - params.flags = 0; - params.parameter_control= user_info->logon_parameters; - - /* Handle plaintext */ - if (!user_info->encrypted) { - DEBUG(3,("Checking plaintext password for %s.\n", - user_info->internal_username)); - params.level = WBC_AUTH_USER_LEVEL_PLAIN; - - params.password.plaintext = user_info->plaintext_password.data; - } else { - DEBUG(3,("Checking encrypted password for %s.\n", - user_info->internal_username)); - params.level = WBC_AUTH_USER_LEVEL_RESPONSE; - - memcpy(params.password.response.challenge, - auth_context->challenge.data, - sizeof(params.password.response.challenge)); - - params.password.response.nt_length = user_info->nt_resp.length; - params.password.response.nt_data = user_info->nt_resp.data; - params.password.response.lm_length = user_info->lm_resp.length; - params.password.response.lm_data = user_info->lm_resp.data; - - } - - /* we are contacting the privileged pipe */ - become_root(); - wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); - unbecome_root(); - - if (!WBC_ERROR_IS_OK(wbc_status)) { - DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n", - wbc_status, wbcErrorString(wbc_status))); - } - - if (wbc_status == WBC_ERR_NO_MEMORY) { - return NT_STATUS_NO_MEMORY; - } - - if (wbc_status == WBC_ERR_AUTH_ERROR) { - nt_status = NT_STATUS(err->nt_status); - wbcFreeMemory(err); - return nt_status; - } - - if (!WBC_ERROR_IS_OK(wbc_status)) { - return NT_STATUS_LOGON_FAILURE; - } - - DEBUG(10,("wbcAuthenticateUserEx succeeded\n")); - - nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, - user_info->smb_name, - user_info->domain, - info, server_info); - wbcFreeMemory(info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - (*server_info)->nss_token |= user_info->was_mapped; - - return nt_status; -} - -/* module initialisation */ -static NTSTATUS auth_init_onefs_wb(struct auth_context *auth_context, const char *param, auth_methods **auth_method) -{ - if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; - } - - (*auth_method)->name = "onefs_wb"; - (*auth_method)->auth = check_onefs_wb_security; - - return NT_STATUS_OK; -} - -NTSTATUS auth_onefs_wb_init(void) -{ - return smb_register_auth(AUTH_INTERFACE_VERSION, "onefs_wb", auth_init_onefs_wb); -} diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c new file mode 100644 index 0000000000..b0af9ffb1d --- /dev/null +++ b/source3/auth/auth_wbc.c @@ -0,0 +1,150 @@ +/* + Unix SMB/CIFS implementation. + + Winbind client authentication mechanism designed to defer all + authentication to the winbind daemon. + + Copyright (C) Tim Potter 2000 + Copyright (C) Andrew Bartlett 2001 - 2002 + Copyright (C) Dan Sledz 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* This auth module is very similar to auth_winbind with 3 distinct + * differences. + * + * 1) Does not fallback to another auth module if winbindd is unavailable + * 2) Does not validate the domain of the user + * 3) Handles unencrypted passwords + * + * The purpose of this module is to defer all authentication decisions (ie: + * local user vs NIS vs LDAP vs AD; encrypted vs plaintext) to the wbc + * compatible daemon. This centeralizes all authentication decisions to a + * single provider. + * + * This auth backend is most useful when used in conjunction with pdb_wbc_sam. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +/* Authenticate a user with a challenge/response */ + +static NTSTATUS check_wbc_security(const struct auth_context *auth_context, + void *my_private_data, + TALLOC_CTX *mem_ctx, + const auth_usersupplied_info *user_info, + auth_serversupplied_info **server_info) +{ + NTSTATUS nt_status; + wbcErr wbc_status; + struct wbcAuthUserParams params; + struct wbcAuthUserInfo *info = NULL; + struct wbcAuthErrorInfo *err = NULL; + + if (!user_info || !auth_context || !server_info) { + return NT_STATUS_INVALID_PARAMETER; + } + /* Send off request */ + + params.account_name = user_info->smb_name; + params.domain_name = user_info->domain; + params.workstation_name = user_info->wksta_name; + + params.flags = 0; + params.parameter_control= user_info->logon_parameters; + + /* Handle plaintext */ + if (!user_info->encrypted) { + DEBUG(3,("Checking plaintext password for %s.\n", + user_info->internal_username)); + params.level = WBC_AUTH_USER_LEVEL_PLAIN; + + params.password.plaintext = user_info->plaintext_password.data; + } else { + DEBUG(3,("Checking encrypted password for %s.\n", + user_info->internal_username)); + params.level = WBC_AUTH_USER_LEVEL_RESPONSE; + + memcpy(params.password.response.challenge, + auth_context->challenge.data, + sizeof(params.password.response.challenge)); + + params.password.response.nt_length = user_info->nt_resp.length; + params.password.response.nt_data = user_info->nt_resp.data; + params.password.response.lm_length = user_info->lm_resp.length; + params.password.response.lm_data = user_info->lm_resp.data; + + } + + /* we are contacting the privileged pipe */ + become_root(); + wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); + unbecome_root(); + + if (!WBC_ERROR_IS_OK(wbc_status)) { + DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n", + wbc_status, wbcErrorString(wbc_status))); + } + + if (wbc_status == WBC_ERR_NO_MEMORY) { + return NT_STATUS_NO_MEMORY; + } + + if (wbc_status == WBC_ERR_AUTH_ERROR) { + nt_status = NT_STATUS(err->nt_status); + wbcFreeMemory(err); + return nt_status; + } + + if (!WBC_ERROR_IS_OK(wbc_status)) { + return NT_STATUS_LOGON_FAILURE; + } + + DEBUG(10,("wbcAuthenticateUserEx succeeded\n")); + + nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, + user_info->smb_name, + user_info->domain, + info, server_info); + wbcFreeMemory(info); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + (*server_info)->nss_token |= user_info->was_mapped; + + return nt_status; +} + +/* module initialisation */ +static NTSTATUS auth_init_wbc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +{ + if (!make_auth_methods(auth_context, auth_method)) { + return NT_STATUS_NO_MEMORY; + } + + (*auth_method)->name = "wbc"; + (*auth_method)->auth = check_wbc_security; + + return NT_STATUS_OK; +} + +NTSTATUS auth_wbc_init(void) +{ + return smb_register_auth(AUTH_INTERFACE_VERSION, "wbc", auth_init_wbc); +} diff --git a/source3/configure.in b/source3/configure.in index bd3d4af40b..d67feccb9b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -414,7 +414,7 @@ AC_SUBST(DYNEXP) dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" +default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer" @@ -1088,7 +1088,7 @@ echo $samba_cv_HAVE_ONEFS if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS]) default_shared_modules="$default_shared_modules vfs_onefs vfs_onefs_shadow_copy perfcount_onefs" - default_static_modules="$default_static_modules auth_onefs_wb pdb_onefs_sam" + default_static_modules="$default_static_modules" ONEFS_LIBS="-lisi_acl -lisi_ecs -lisi_event -lisi_util" # Need to also add general libs for oplocks support save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat" @@ -6130,7 +6130,7 @@ SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o passdb/pdb_nds.o, "bin/ldapsam.$SHLIBEXT" [ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] ) SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB) SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB) -SMB_MODULE(pdb_onefs_sam, passdb/pdb_onefs_sam.o, "bin/onefs_sam.$SHLIBEXT", PDB) +SMB_MODULE(pdb_wbc_sam, passdb/pdb_wbc_sam.o, "bin/wbc_sam.$SHLIBEXT", PDB) SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o) @@ -6173,7 +6173,7 @@ SMB_SUBSYSTEM(CHARSET,lib/iconv.o) SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH) SMB_MODULE(auth_unix, \$(AUTH_UNIX_OBJ), "bin/unix.$SHLIBEXT", AUTH) SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH) -SMB_MODULE(auth_onefs_wb, \$(AUTH_ONEFS_WB_OBJ), "bin/onefs_wb.$SHLIBEXT", AUTH) +SMB_MODULE(auth_wbc, \$(AUTH_WBC_OBJ), "bin/wbc.$SHLIBEXT", AUTH) SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH) SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH) SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH) diff --git a/source3/passdb/pdb_onefs_sam.c b/source3/passdb/pdb_onefs_sam.c deleted file mode 100644 index 51b8618aad..0000000000 --- a/source3/passdb/pdb_onefs_sam.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling for wbclient - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Jelmer Vernooij 2002 - Copyright (C) Simo Sorce 2003 - Copyright (C) Volker Lendecke 2006 - Copyright (C) Dan Sledz 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/*************************************************************************** - Default implementations of some functions. - ****************************************************************************/ -static NTSTATUS _pdb_onefs_sam_getsampw(struct pdb_methods *methods, - struct samu *user, - const struct passwd *pwd) -{ - NTSTATUS result = NT_STATUS_OK; - - if (pwd == NULL) - return NT_STATUS_NO_SUCH_USER; - - memset(user, 0, sizeof(user)); - - /* Can we really get away with this little of information */ - user->methods = methods; - result = samu_set_unix(user, pwd); - - return result; -} - -static NTSTATUS pdb_onefs_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) -{ - return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwnam(sname)); -} - -static NTSTATUS pdb_onefs_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) -{ - return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwsid(sid)); -} - -static bool pdb_onefs_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, - DOM_SID *sid) -{ - return winbind_uid_to_sid(sid, uid); -} - -static bool pdb_onefs_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, - DOM_SID *sid) -{ - return winbind_gid_to_sid(sid, gid); -} - -static bool pdb_onefs_sam_sid_to_id(struct pdb_methods *methods, - const DOM_SID *sid, - union unid_t *id, enum lsa_SidType *type) -{ - if (winbind_sid_to_uid(&id->uid, sid)) { - *type = SID_NAME_USER; - } else if (winbind_sid_to_gid(&id->gid, sid)) { - /* We assume all gids are groups, not aliases */ - *type = SID_NAME_DOM_GRP; - } else { - return false; - } - - return true; -} - -static NTSTATUS pdb_onefs_sam_enum_group_members(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - const DOM_SID *group, - uint32 **pp_member_rids, - size_t *p_num_members) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - struct samu *user, - DOM_SID **pp_sids, - gid_t **pp_gids, - size_t *p_num_groups) -{ - size_t i; - const char *username = pdb_get_username(user); - - if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { - return NT_STATUS_NO_SUCH_USER; - } - - if (*p_num_groups == 0) { - smb_panic("primary group missing"); - } - - *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups); - - if (*pp_sids == NULL) { - TALLOC_FREE(*pp_gids); - return NT_STATUS_NO_MEMORY; - } - - for (i=0; i < *p_num_groups; i++) { - gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_onefs_sam_lookup_rids(struct pdb_methods *methods, - const DOM_SID *domain_sid, - int num_rids, - uint32 *rids, - const char **names, - enum lsa_SidType *attrs) -{ - NTSTATUS result = NT_STATUS_OK; - char *domain = NULL; - char **account_names = NULL; - char name[256]; - enum lsa_SidType *attr_list = NULL; - int i; - - if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids, - (const char **)&domain, - (const char ***)&account_names, &attr_list)) - { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType)); - - for (i=0; int_name, sizeof(map->nt_name), "%s%c%s", - domain, *lp_winbind_separator(), name); - map->sid_name_use = name_type; - map->sid = *sid; - map->gid = gid; - return true; -} - -static NTSTATUS pdb_onefs_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, - DOM_SID sid) -{ - NTSTATUS result = NT_STATUS_OK; - char *name = NULL; - char *domain = NULL; - enum lsa_SidType name_type; - gid_t gid; - - if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, - (const char **) &name, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_sid_to_gid(&gid, &sid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - TALLOC_FREE(name); - TALLOC_FREE(domain); - return result; -} - -static NTSTATUS pdb_onefs_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, - gid_t gid) -{ - NTSTATUS result = NT_STATUS_OK; - char *name = NULL; - char *domain = NULL; - DOM_SID sid; - enum lsa_SidType name_type; - - if (!winbind_gid_to_sid(&sid, gid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, - (const char **)&name, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - TALLOC_FREE(name); - TALLOC_FREE(domain); - - return result; -} - -static NTSTATUS pdb_onefs_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, - const char *name) -{ - NTSTATUS result = NT_STATUS_OK; - char *user_name = NULL; - char *domain = NULL; - DOM_SID sid; - gid_t gid; - enum lsa_SidType name_type; - - if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_sid_to_gid(&gid, &sid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - - return result; -} - -static NTSTATUS pdb_onefs_sam_enum_group_mapping(struct pdb_methods *methods, - const DOM_SID *sid, enum lsa_SidType sid_name_use, - GROUP_MAP **pp_rmap, size_t *p_num_entries, - bool unix_only) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_get_aliasinfo(struct pdb_methods *methods, - const DOM_SID *sid, - struct acct_info *info) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_enum_aliasmem(struct pdb_methods *methods, - const DOM_SID *alias, DOM_SID **pp_members, - size_t *p_num_members) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_alias_memberships(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - const DOM_SID *domain_sid, - const DOM_SID *members, - size_t num_members, - uint32 **pp_alias_rids, - size_t *p_num_alias_rids) -{ - if (!winbind_get_sid_aliases(mem_ctx, domain_sid, - members, num_members, pp_alias_rids, p_num_alias_rids)) - return NT_STATUS_UNSUCCESSFUL; - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char *location) -{ - NTSTATUS result; - - if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) { - return result; - } - - (*pdb_method)->name = "onefs_sam"; - - (*pdb_method)->getsampwnam = pdb_onefs_sam_getsampwnam; - (*pdb_method)->getsampwsid = pdb_onefs_sam_getsampwsid; - - (*pdb_method)->getgrsid = pdb_onefs_sam_getgrsid; - (*pdb_method)->getgrgid = pdb_onefs_sam_getgrgid; - (*pdb_method)->getgrnam = pdb_onefs_sam_getgrnam; - (*pdb_method)->enum_group_mapping = pdb_onefs_sam_enum_group_mapping; - (*pdb_method)->enum_group_members = pdb_onefs_sam_enum_group_members; - (*pdb_method)->enum_group_memberships = pdb_onefs_sam_enum_group_memberships; - (*pdb_method)->get_aliasinfo = pdb_onefs_sam_get_aliasinfo; - (*pdb_method)->enum_aliasmem = pdb_onefs_sam_enum_aliasmem; - (*pdb_method)->enum_alias_memberships = pdb_onefs_sam_alias_memberships; - (*pdb_method)->lookup_rids = pdb_onefs_sam_lookup_rids; - (*pdb_method)->get_account_policy = pdb_onefs_sam_get_account_policy; - (*pdb_method)->set_account_policy = pdb_onefs_sam_set_account_policy; - (*pdb_method)->uid_to_sid = pdb_onefs_sam_uid_to_sid; - (*pdb_method)->gid_to_sid = pdb_onefs_sam_gid_to_sid; - (*pdb_method)->sid_to_id = pdb_onefs_sam_sid_to_id; - - (*pdb_method)->search_groups = pdb_onefs_sam_search_groups; - (*pdb_method)->search_aliases = pdb_onefs_sam_search_aliases; - - (*pdb_method)->get_trusteddom_pw = pdb_onefs_sam_get_trusteddom_pw; - (*pdb_method)->set_trusteddom_pw = pdb_onefs_sam_set_trusteddom_pw; - (*pdb_method)->del_trusteddom_pw = pdb_onefs_sam_del_trusteddom_pw; - (*pdb_method)->enum_trusteddoms = pdb_onefs_sam_enum_trusteddoms; - - (*pdb_method)->private_data = NULL; - (*pdb_method)->free_private_data = NULL; - - return NT_STATUS_OK; -} - -NTSTATUS pdb_onefs_sam_init(void) -{ - return smb_register_passdb(PASSDB_INTERFACE_VERSION, "onefs_sam", pdb_init_onefs_sam); -} diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c new file mode 100644 index 0000000000..33dc03fe4c --- /dev/null +++ b/source3/passdb/pdb_wbc_sam.c @@ -0,0 +1,448 @@ +/* + Unix SMB/CIFS implementation. + + Password and authentication handling by wbclient + + Copyright (C) Andrew Bartlett 2002 + Copyright (C) Jelmer Vernooij 2002 + Copyright (C) Simo Sorce 2003 + Copyright (C) Volker Lendecke 2006 + Copyright (C) Dan Sledz 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* This passdb module retrieves full passdb information for local users and + * groups from a wbclient compatible daemon. + * + * The purpose of this module is to defer all SAM authorization information + * storage and retrieval to a wbc compatible daemon. + * + * This passdb backend is most useful when used in conjunction with auth_wbc. + * + * A few current limitations of this module are: + * - read only interface + * - no privileges + */ + +#include "includes.h" + +/*************************************************************************** + Default implementations of some functions. + ****************************************************************************/ +static NTSTATUS _pdb_wbc_sam_getsampw(struct pdb_methods *methods, + struct samu *user, + const struct passwd *pwd) +{ + NTSTATUS result = NT_STATUS_OK; + + if (pwd == NULL) + return NT_STATUS_NO_SUCH_USER; + + memset(user, 0, sizeof(user)); + + /* Can we really get away with this little of information */ + user->methods = methods; + result = samu_set_unix(user, pwd); + + return result; +} + +static NTSTATUS pdb_wbc_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) +{ + return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwnam(sname)); +} + +static NTSTATUS pdb_wbc_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) +{ + return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwsid(sid)); +} + +static bool pdb_wbc_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, + DOM_SID *sid) +{ + return winbind_uid_to_sid(sid, uid); +} + +static bool pdb_wbc_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, + DOM_SID *sid) +{ + return winbind_gid_to_sid(sid, gid); +} + +static bool pdb_wbc_sam_sid_to_id(struct pdb_methods *methods, + const DOM_SID *sid, + union unid_t *id, enum lsa_SidType *type) +{ + if (winbind_sid_to_uid(&id->uid, sid)) { + *type = SID_NAME_USER; + } else if (winbind_sid_to_gid(&id->gid, sid)) { + /* We assume all gids are groups, not aliases */ + *type = SID_NAME_DOM_GRP; + } else { + return false; + } + + return true; +} + +static NTSTATUS pdb_wbc_sam_enum_group_members(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + const DOM_SID *group, + uint32 **pp_member_rids, + size_t *p_num_members) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + struct samu *user, + DOM_SID **pp_sids, + gid_t **pp_gids, + size_t *p_num_groups) +{ + size_t i; + const char *username = pdb_get_username(user); + + if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { + return NT_STATUS_NO_SUCH_USER; + } + + if (*p_num_groups == 0) { + smb_panic("primary group missing"); + } + + *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups); + + if (*pp_sids == NULL) { + TALLOC_FREE(*pp_gids); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i < *p_num_groups; i++) { + gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]); + } + + return NT_STATUS_OK; +} + +static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods, + const DOM_SID *domain_sid, + int num_rids, + uint32 *rids, + const char **names, + enum lsa_SidType *attrs) +{ + NTSTATUS result = NT_STATUS_OK; + char *domain = NULL; + char **account_names = NULL; + char name[256]; + enum lsa_SidType *attr_list = NULL; + int i; + + if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids, + (const char **)&domain, + (const char ***)&account_names, &attr_list)) + { + result = NT_STATUS_NONE_MAPPED; + goto done; + } + + memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType)); + + for (i=0; int_name, sizeof(map->nt_name), "%s%c%s", + domain, *lp_winbind_separator(), name); + map->sid_name_use = name_type; + map->sid = *sid; + map->gid = gid; + return true; +} + +static NTSTATUS pdb_wbc_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, + DOM_SID sid) +{ + NTSTATUS result = NT_STATUS_OK; + char *name = NULL; + char *domain = NULL; + enum lsa_SidType name_type; + gid_t gid; + + if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, + (const char **) &name, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_sid_to_gid(&gid, &sid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + TALLOC_FREE(name); + TALLOC_FREE(domain); + return result; +} + +static NTSTATUS pdb_wbc_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, + gid_t gid) +{ + NTSTATUS result = NT_STATUS_OK; + char *name = NULL; + char *domain = NULL; + DOM_SID sid; + enum lsa_SidType name_type; + + if (!winbind_gid_to_sid(&sid, gid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, + (const char **)&name, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + TALLOC_FREE(name); + TALLOC_FREE(domain); + + return result; +} + +static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, + const char *name) +{ + NTSTATUS result = NT_STATUS_OK; + char *user_name = NULL; + char *domain = NULL; + DOM_SID sid; + gid_t gid; + enum lsa_SidType name_type; + + if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_sid_to_gid(&gid, &sid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + + return result; +} + +static NTSTATUS pdb_wbc_sam_enum_group_mapping(struct pdb_methods *methods, + const DOM_SID *sid, enum lsa_SidType sid_name_use, + GROUP_MAP **pp_rmap, size_t *p_num_entries, + bool unix_only) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_get_aliasinfo(struct pdb_methods *methods, + const DOM_SID *sid, + struct acct_info *info) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_enum_aliasmem(struct pdb_methods *methods, + const DOM_SID *alias, DOM_SID **pp_members, + size_t *p_num_members) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_alias_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + const DOM_SID *domain_sid, + const DOM_SID *members, + size_t num_members, + uint32 **pp_alias_rids, + size_t *p_num_alias_rids) +{ + if (!winbind_get_sid_aliases(mem_ctx, domain_sid, + members, num_members, pp_alias_rids, p_num_alias_rids)) + return NT_STATUS_UNSUCCESSFUL; + + return NT_STATUS_OK; +} + +static NTSTATUS pdb_init_wbc_sam(struct pdb_methods **pdb_method, const char *location) +{ + NTSTATUS result; + + if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) { + return result; + } + + (*pdb_method)->name = "wbc_sam"; + + (*pdb_method)->getsampwnam = pdb_wbc_sam_getsampwnam; + (*pdb_method)->getsampwsid = pdb_wbc_sam_getsampwsid; + + (*pdb_method)->getgrsid = pdb_wbc_sam_getgrsid; + (*pdb_method)->getgrgid = pdb_wbc_sam_getgrgid; + (*pdb_method)->getgrnam = pdb_wbc_sam_getgrnam; + (*pdb_method)->enum_group_mapping = pdb_wbc_sam_enum_group_mapping; + (*pdb_method)->enum_group_members = pdb_wbc_sam_enum_group_members; + (*pdb_method)->enum_group_memberships = pdb_wbc_sam_enum_group_memberships; + (*pdb_method)->get_aliasinfo = pdb_wbc_sam_get_aliasinfo; + (*pdb_method)->enum_aliasmem = pdb_wbc_sam_enum_aliasmem; + (*pdb_method)->enum_alias_memberships = pdb_wbc_sam_alias_memberships; + (*pdb_method)->lookup_rids = pdb_wbc_sam_lookup_rids; + (*pdb_method)->get_account_policy = pdb_wbc_sam_get_account_policy; + (*pdb_method)->set_account_policy = pdb_wbc_sam_set_account_policy; + (*pdb_method)->uid_to_sid = pdb_wbc_sam_uid_to_sid; + (*pdb_method)->gid_to_sid = pdb_wbc_sam_gid_to_sid; + (*pdb_method)->sid_to_id = pdb_wbc_sam_sid_to_id; + + (*pdb_method)->search_groups = pdb_wbc_sam_search_groups; + (*pdb_method)->search_aliases = pdb_wbc_sam_search_aliases; + + (*pdb_method)->get_trusteddom_pw = pdb_wbc_sam_get_trusteddom_pw; + (*pdb_method)->set_trusteddom_pw = pdb_wbc_sam_set_trusteddom_pw; + (*pdb_method)->del_trusteddom_pw = pdb_wbc_sam_del_trusteddom_pw; + (*pdb_method)->enum_trusteddoms = pdb_wbc_sam_enum_trusteddoms; + + (*pdb_method)->private_data = NULL; + (*pdb_method)->free_private_data = NULL; + + return NT_STATUS_OK; +} + +NTSTATUS pdb_wbc_sam_init(void) +{ + return smb_register_passdb(PASSDB_INTERFACE_VERSION, "wbc_sam", pdb_init_wbc_sam); +} -- cgit From cde5724780c0e52705e0f6e7cd41e0c884afbb40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 17:32:22 -0800 Subject: Added torture test from a usage case from the Apple OS/X client. Setting an attribute on a stream fnum must change the attribute on the base file. Jeremy. --- source4/torture/raw/streams.c | 119 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c index 0622e0809d..bf87bd224f 100644 --- a/source4/torture/raw/streams.c +++ b/source4/torture/raw/streams.c @@ -1535,6 +1535,121 @@ static bool test_stream_large_streaminfo(struct torture_context *tctx, return ret; } +/* Test the effect of setting attributes on a stream. */ +static bool test_stream_attributes(struct torture_context *tctx, + struct smbcli_state *cli, + TALLOC_CTX *mem_ctx) +{ + bool ret = true; + NTSTATUS status; + union smb_open io; + const char *fname = BASEDIR "\\stream_attr.txt"; + const char *stream = "Stream One:$DATA"; + const char *fname_stream; + int fnum = -1; + union smb_fileinfo finfo; + union smb_setfileinfo sfinfo; + time_t basetime = (time(NULL) - 86400) & ~1; + + printf ("(%s) testing attribute setting on stream\n", __location__); + + fname_stream = talloc_asprintf(mem_ctx, "%s:%s", fname, stream); + + /* Create a file with a stream with attribute FILE_ATTRIBUTE_ARCHIVE. */ + ret = create_file_with_stream(tctx, cli, mem_ctx, fname, + fname_stream); + if (!ret) { + goto done; + } + + ZERO_STRUCT(finfo); + finfo.generic.level = RAW_FILEINFO_BASIC_INFO; + finfo.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + CHECK_STATUS(status, NT_STATUS_OK); + + if (finfo.basic_info.out.attrib != FILE_ATTRIBUTE_ARCHIVE) { + printf("(%s) Incorrect attrib %x - should be %x\n", \ + __location__, (unsigned int)finfo.basic_info.out.attrib, + (unsigned int)FILE_ATTRIBUTE_ARCHIVE); + ret = false; + goto done; + } + + /* Now open the stream name. */ + + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA| + SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL|SEC_FILE_WRITE_ATTRIBUTE); + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.file_attr = 0; + io.ntcreatex.in.share_access = 0; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname_stream; + + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + fnum = io.ntcreatex.out.file.fnum; + + /* Change the attributes + time on the stream fnum. */ + ZERO_STRUCT(sfinfo); + sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY; + unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime); + + sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION; + sfinfo.generic.in.file.fnum = fnum; + status = smb_raw_setfileinfo(cli->tree, &sfinfo); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { + printf("(%s) %s - %s (should be %s)\n", __location__, "SETATTR", + nt_errstr(status), nt_errstr(NT_STATUS_OK)); + ret = false; + goto done; + } + + smbcli_close(cli->tree, fnum); + fnum = -1; + + ZERO_STRUCT(finfo); + finfo.generic.level = RAW_FILEINFO_ALL_INFO; + finfo.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (!NT_STATUS_IS_OK(status)) { + printf("(%s) %s pathinfo - %s\n", __location__, "SETATTRE", nt_errstr(status)); + ret = false; + goto done; + } + + if (finfo.all_info.out.attrib != FILE_ATTRIBUTE_READONLY) { + printf("(%s) attrib incorrect. Was 0x%x, should be 0x%x\n", + __location__, + (unsigned int)finfo.all_info.out.attrib, + (unsigned int)FILE_ATTRIBUTE_READONLY); + ret = false; + goto done; + } + + if (nt_time_to_unix(finfo.all_info.out.write_time) != basetime) { + printf("(%s) time incorrect.\n", + __location__); + ret = false; + goto done; + } + + done: + + if (fnum != -1) { + smbcli_close(cli->tree, fnum); + } + smbcli_unlink(cli->tree, fname); + return ret; +} + /* basic testing of streams calls */ @@ -1566,6 +1681,10 @@ bool torture_raw_streams(struct torture_context *torture, smb_raw_exit(cli->session); ret &= test_stream_create_disposition(torture, cli, torture); smb_raw_exit(cli->session); + + ret &= test_stream_attributes(torture, cli, torture); + smb_raw_exit(cli->session); + /* ret &= test_stream_large_streaminfo(torture, cli, torture); */ /* smb_raw_exit(cli->session); */ -- cgit From ebe1aa9340d190b2ebcfd2c96f68c7771cccdf01 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 18:03:49 -0800 Subject: Allow set attributes on a stream fnum to be redirected to the base filename. Fixes the new RAW-STREAMS torture test. Jeremy. --- source3/smbd/trans2.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 759e520866..433b8a008d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4972,6 +4972,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, ****************************************************************************/ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, + files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 dosmode) @@ -4980,6 +4981,14 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + if (fsp) { + if (fsp->base_fsp) { + fname = fsp->base_fsp->fsp_name; + } else { + fname = fsp->fsp_name; + } + } + if (dosmode) { if (S_ISDIR(psbuf->st_mode)) { dosmode |= aDIR; @@ -5723,12 +5732,11 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, /* Set the attributes */ dosmode = IVAL(pdata,32); - status = smb_set_file_dosmode(conn, fname, psbuf, dosmode); + status = smb_set_file_dosmode(conn, fsp, fname, psbuf, dosmode); if (!NT_STATUS_IS_OK(status)) { return status; } - /* access time */ ft.atime = interpret_long_date(pdata+8); -- cgit From 7040d94149d8538c0b731b9e62b9b4c7807841b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Feb 2009 13:14:36 +1100 Subject: Prepare for a quick alpha7 release to help simo meet Fedora deadlines While there isn't much in this release, there is enough to be worth cutting the tarball, and not much cost in doing so. Andrew Bartlett --- WHATSNEW4.txt | 101 ++++++++++++---------------------------------------------- 1 file changed, 21 insertions(+), 80 deletions(-) diff --git a/WHATSNEW4.txt b/WHATSNEW4.txt index 03cd72c518..2093a4ee1f 100644 --- a/WHATSNEW4.txt +++ b/WHATSNEW4.txt @@ -1,4 +1,4 @@ -What's new in Samba 4 alpha6 +What's new in Samba 4 alpha7 ============================ Samba 4 is the ambitious next version of the Samba suite that is being @@ -6,13 +6,13 @@ developed in parallel to the stable 3.0 series. The main emphasis in this branch is support for the Active Directory logon protocols used by Windows 2000 and above. -Samba4 alpha6 follows on from the alpha release series we have been +Samba4 alpha7 follows on from the alpha release series we have been publishing since September 2007 WARNINGS ======== -Samba4 alpha6 is not a final Samba release. That is more a reference +Samba4 alpha7 is not a final Samba release. That is more a reference to Samba4's lack of the features we expect you will need than a statement of code quality, but clearly it hasn't seen a broad deployment yet. If you were to upgrade Samba3 (or indeed Windows) to @@ -62,85 +62,30 @@ working on modules to map between AD-like behaviours and this backend. We are aiming for Samba 4 to be powerful frontend to large directories. -CHANGES SINCE Alpha5 +CHANGES SINCE alpha6 ===================== -In the time since Samba4 Alpha5 was released in June 2008, Samba has +In the time since Samba4 alpha6 was released in Janurary 2009, Samba has continued to evolve, but you may particularly notice these areas (in no particular order): - The source code for various libraries that are used by both Samba 3 and - Samba 4 are now shared between the two rather than duplicated - (and being slightly diverged). + OpenLDAP Multi Master Replication can now also replicate the OpenLDAP + configuration itself. - The tevent library has been split out and is now usable on its own. + Support for Windows 7 beta as a member of the Samba4 domain - Several crash bugs and memory leaks in the registry library have been fixed. + Issues with the nesting of LDB transactions have been fixed - The Python modules have been extended and are no longer generated using SWIG. + A number of internal libraries (tevent, auth in particular has been + updated for easier use outside Samba4 - Stream renames are now supported. - - The provision script now has an interactive mode. - - The (broken) copy of CTDB has been removed. - - More work towards supporting an OpenLDAP backend. - - Initial work on using the Microsoft LDAP schema. - - The storage of schemas in LDB is now much more efficient. - - Support for extended DNs in LDB has been added. - - Incoming trusts are now supported. - - Compatibility of the registry server with several Windows versions has been - improved. - - Improvements to LSA.idl for better functionality in the usrmgr.exe. - - Improved handling of non-standard characters in passwords. - - The embedded JavaScript library has been removed in favor of Python. - - The WMI implementation has been re-added, but does not completely work yet. - - xpress compression is now supported in the NDR layer. - - The main binary is now named "samba" rather than "smbd". - - A simple script for setting the expiration of a user was added. - - The LDB library is now completely asynchronous internally. - - Various unknowns and correctness issues in the drsblobs and drsuapi RPC - interface implementations have been fixed. - - It is now possible to connect to an LDAP backend using SASL credentials. - - Multi-fragment NTtrans request support has been added. - - The DCE/RPC server can now listen on a separate pipe to allow DCE/RPC - connections forwarded from Samba 3. The user credentials are provided - by the client. - - A large number of bugs in the SMB2 implementation have been fixed. - - Auxiliary classes in LDAP schema conversion are now collapsed. - - Several tests have been added to the SMB testsuite. - - Object GUIDs in DCE/RPC connections are now dealt with properly. - - The correctness of the LSA and NETLOGON implementations has been - improved. - - Multi Master Replication configuration can now be generated - for OpenLDAP. - -These are just some of the highlights of the work done in the past few -months. More details can be found in our GIT history. + spoolss IDL updates to bring Samba3 to use PIDL code, and to merge + the corrected IDL back into Samba4 + + Fixes to allow use of C++ compilers and to increase portability + +These are just some of the highlights of the work done in the past +month. More details can be found in our GIT history. CHANGES @@ -163,17 +108,13 @@ KNOWN ISSUES - Clock Synchronisation is critical. Many 'wrong password' errors are actually due to Kerberos objecting to a clock skew between client - and server. (The NTP work in the previous alpha is partly to assist + and server. (The NTP work in the previous alphas are partly to assist with this problem). -- Samba4 alpha6 is currently only portable to recent Linux +- Samba4 alpha7 is currently only portable to recent Linux distributions. Work to return support for other Unix varients is - expected during the next alpha cycle + expected during the next alpha cycles -- Samba4 alpha6 is incompatible with GnuTLS 2.0, found in Fedora 9 and - recent Ubuntu releases. GnuTLS use may be disabled using the - --disable-gnutls argument to ./configure. (otherwise 'make test' and - LDAPS operations will hang). RUNNING Samba4 ============== -- cgit From d75df717336e063f52af1415f99b6e16ccbf918c Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 24 Feb 2009 20:53:46 -0600 Subject: Fix guest mounts guest session setup, login (user id) as anonymous. This patch is for samba bugzilla bug 4640. Signed-off-by: Shirish Pargaonkar Acked-by: Jeff Layton Signed-off-by: Steve French --- source3/client/mount.cifs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index ae8a7fd186..8623d3c04b 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -649,7 +649,9 @@ static int parse_options(char ** optionsp, int * filesys_flags) } else if (strncmp(data, "exec", 4) == 0) { *filesys_flags &= ~MS_NOEXEC; } else if (strncmp(data, "guest", 5) == 0) { - got_password=1; + user_name = (char *)calloc(1, 1); + got_user = 1; + got_password = 1; } else if (strncmp(data, "ro", 2) == 0) { *filesys_flags |= MS_RDONLY; } else if (strncmp(data, "rw", 2) == 0) { -- cgit From afc7e45a4ccf8505e4c598334e339e79ba036057 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 21:53:30 -0800 Subject: s3 OneFS: Fix uninitialized variable --- source3/modules/onefs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index b8097b6455..a1bfa6e121 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -890,7 +890,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { struct ifs_security_descriptor sd = {}; - int fd; + int fd = -1; bool fopened = false; NTSTATUS status; -- cgit From c2cdb4ad5c9398ef0d3310613107999f8d33c7ce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Feb 2009 17:43:07 +1100 Subject: Work around ndr_unpack failing on structures with relative pointers. This disgusting hack works around the fact that ndr_pull_struct_blob_all will always fail on structures with relative pointers. So, map ndr_unpack to ndr_pull_struct_blob_all only if we don't have any relative pointers in this structure. Andrew Bartlett --- pidl/lib/Parse/Pidl/Samba4/Python.pm | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 48785f5b0a..6099fe5cae 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -275,7 +275,24 @@ sub PythonStruct($$$$$$) $self->pidl("if (!PyArg_ParseTuple(args, \"s#:__ndr_unpack__\", &blob.data, &blob.length))"); $self->pidl("\treturn NULL;"); $self->pidl(""); - $self->pidl("err = ndr_pull_struct_blob_all(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);"); + + # This disgusting hack works around the fact that ndr_pull_struct_blob_all will always fail on structures with relative pointers. + # So, map ndr_unpack to ndr_pull_struct_blob_all only if we don't have any relative pointers in this + my $got_relative = 0; + if ($#{$d->{ELEMENTS}} > -1) { + foreach my $e (@{$d->{ELEMENTS}}) { + my $l = $e->{LEVELS}[0]; + if ($l->{TYPE} eq "POINTER" and ($l->{POINTER_TYPE} eq "relative")) { + $got_relative = 1; + last; + } + } + } + if ($got_relative == 0) { + $self->pidl("err = ndr_pull_struct_blob_all(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);"); + } else { + $self->pidl("err = ndr_pull_struct_blob(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);"); + } $self->pidl("if (err != NDR_ERR_SUCCESS) {"); $self->indent; $self->pidl("PyErr_SetNdrError(err);"); -- cgit From 2f1b12890a31baceee6a4d446b4782caefb1fcaa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Feb 2009 17:52:00 +1100 Subject: Credit tridge's work on fixing GnuTLS --- WHATSNEW4.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WHATSNEW4.txt b/WHATSNEW4.txt index 2093a4ee1f..2df23fd624 100644 --- a/WHATSNEW4.txt +++ b/WHATSNEW4.txt @@ -83,6 +83,8 @@ continued to evolve, but you may particularly notice these areas the corrected IDL back into Samba4 Fixes to allow use of C++ compilers and to increase portability + + Fixed TLS (SSL) support with modern versions of GnuTLS These are just some of the highlights of the work done in the past month. More details can be found in our GIT history. -- cgit From dc0e46afb7018a1da666729c6d61e8ea85dcf07d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 08:42:33 +0100 Subject: s4:build: add some comments to the SMB_EXT_LIB() definition metze --- source4/build/m4/public.m4 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index 1927e9977f..ffdf92f784 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -157,6 +157,13 @@ mkinclude $1 " ]) +dnl +dnl SMB_EXT_LIB() just specifies the details of the library. +dnl Note: the library isn't enabled by default. +dnl You need to enable it with SMB_ENABLE(name) if configure +dnl find it should be used. E.g. it should not be enabled +dnl if the library is present, but the header file is missing. +dnl dnl SMB_EXT_LIB(name,libs,cflags,cppflags,ldflags) AC_DEFUN([SMB_EXT_LIB], [ -- cgit From 662f996b1554508baf7344b8618f152c179f1680 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Wed, 25 Feb 2009 00:11:31 -0800 Subject: s3: Fix 'assignment differ in signedness' warning --- source3/auth/auth_wbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c index b0af9ffb1d..580c8b550d 100644 --- a/source3/auth/auth_wbc.c +++ b/source3/auth/auth_wbc.c @@ -74,7 +74,7 @@ static NTSTATUS check_wbc_security(const struct auth_context *auth_context, user_info->internal_username)); params.level = WBC_AUTH_USER_LEVEL_PLAIN; - params.password.plaintext = user_info->plaintext_password.data; + params.password.plaintext = (char *)user_info->plaintext_password.data; } else { DEBUG(3,("Checking encrypted password for %s.\n", user_info->internal_username)); -- cgit From eb5efd1978acd38cf6cc97e067b5105743ca5469 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 23:38:42 -0800 Subject: s4 heimdal: Link libintl correctly --- source4/heimdal_build/internal.m4 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index 50a3c8adda..a48777fab1 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -170,6 +170,12 @@ SMB_ENABLE(OPENPTY,YES) SMB_EXT_LIB(OPENPTY,[${OPENPTY_LIBS}],[${OPENPTY_CFLAGS}],[${OPENPTY_CPPFLAGS}],[${OPENPTY_LDFLAGS}]) +AC_CHECK_LIB_EXT(intl, INTL_LIBS, gettext) + +SMB_ENABLE(INTL,YES) + +SMB_EXT_LIB(INTL, $INTL_LIBS) + smb_save_LIBS=$LIBS RESOLV_LIBS="" LIBS="" -- cgit From 4823e988b6360646931f9b6369bf7b8f512069a8 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Wed, 25 Feb 2009 20:26:27 +1100 Subject: WHATSNEW updates Signed-off-by: Andrew Bartlett --- WHATSNEW4.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/WHATSNEW4.txt b/WHATSNEW4.txt index 2df23fd624..7c637ccd66 100644 --- a/WHATSNEW4.txt +++ b/WHATSNEW4.txt @@ -69,8 +69,11 @@ In the time since Samba4 alpha6 was released in Janurary 2009, Samba has continued to evolve, but you may particularly notice these areas (in no particular order): - OpenLDAP Multi Master Replication can now also replicate the OpenLDAP - configuration itself. + Multi Master Replication (MMR) configuration can now be generated + for the OpenLDAP-Backend. + + OpenLDAP-Online-Configuration (olc) can now be generated for the + OpenLDAP-Backend. (OpenLDAP-Versions >=2.4.15 required). Support for Windows 7 beta as a member of the Samba4 domain -- cgit From 9d165fa5c69d3c98d1a76a155bb794a7e4c9744a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 01:07:50 +0100 Subject: s3-spoolss: add rpccli_spoolss_addprinterex convenience wrapper. Guenther --- source3/include/proto.h | 3 +++ source3/rpc_client/cli_spoolss.c | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9366607995..5c9e5d3170 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5476,6 +5476,9 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, union spoolss_DriverInfo *info, uint32_t *server_major_version, uint32_t *server_minor_version); +WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinterInfoCtr *info_ctr); WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 19e9aae0f8..20599d12b6 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -137,6 +137,48 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, return werror; } +/********************************************************************** + convencience wrapper around rpccli_spoolss_AddPrinterEx +**********************************************************************/ + +WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinterInfoCtr *info_ctr) +{ + WERROR result; + NTSTATUS status; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + struct spoolss_UserLevelCtr userlevel_ctr; + struct spoolss_UserLevel1 level1; + struct policy_handle handle; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + + level1.size = 28; + level1.build = 1381; + level1.major = 2; + level1.minor = 0; + level1.processor = 0; + level1.client = talloc_asprintf(mem_ctx, "\\\\%s", global_myname()); + W_ERROR_HAVE_NO_MEMORY(level1.client); + level1.user = cli->auth->user_name; + + userlevel_ctr.level = 1; + userlevel_ctr.user_info.level1 = &level1; + + status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx, + cli->srv_name_slash, + info_ctr, + &devmode_ctr, + &secdesc_ctr, + &userlevel_ctr, + &handle, + &result); + return result; +} + /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ -- cgit From 9e3178e8387cd85858a145bb4918073f91127d20 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 10:54:19 +0100 Subject: Attempt to fix the OpenChange build -- sorry for the break --- lib/tevent/tevent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 33747f0986..b3d1c6d59a 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -31,7 +31,7 @@ #include #include #include -#include <../lib/replace/replace.h> +#include struct tevent_context; struct tevent_ops; -- cgit From 6366084c4a7aa4845816cef6f1782e9d1c1f138c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 14 Feb 2009 03:07:01 +0100 Subject: s3-spoolss: add rpccli_spoolss_getprinter convenience wrapper. Guenther --- source3/include/proto.h | 6 +++++ source3/rpc_client/cli_spoolss.c | 50 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 5c9e5d3170..9ed8901fb3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5479,6 +5479,12 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct spoolss_SetPrinterInfoCtr *info_ctr); +WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t level, + uint32_t offered, + union spoolss_PrinterInfo *info); WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 20599d12b6..4fe05a5ff4 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -179,6 +179,55 @@ WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, return result; } +/********************************************************************** + convencience wrapper around rpccli_spoolss_GetPrinter +**********************************************************************/ + +WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t level, + uint32_t offered, + union spoolss_PrinterInfo *info) +{ + NTSTATUS status; + WERROR werror; + DATA_BLOB buffer; + uint32_t needed; + + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + } + + status = rpccli_spoolss_GetPrinter(cli, mem_ctx, + handle, + level, + (offered > 0) ? &buffer : NULL, + offered, + info, + &needed, + &werror); + + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + + status = rpccli_spoolss_GetPrinter(cli, mem_ctx, + handle, + level, + &buffer, + offered, + info, + &needed, + &werror); + } + + return werror; +} + /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ @@ -1401,5 +1450,4 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me return out.status; } - /** @} **/ -- cgit From 1a77218dca0222aafff81aae6cd17462706e226e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 14 Feb 2009 03:08:06 +0100 Subject: s3-rpcclient: use rpccli_spoolss_SetPrinter and rpccli_spoolss_getprinter. Guenther --- source3/rpcclient/cmd_spoolss.c | 185 +++++++++++++++++++++++++++------------- 1 file changed, 124 insertions(+), 61 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 17ff818de6..4e1c7f1422 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -283,12 +283,10 @@ static void display_print_info_3(PRINTER_INFO_3 *i3) /**************************************************************************** ****************************************************************************/ -static void display_print_info_7(PRINTER_INFO_7 *i7) +static void display_print_info7(struct spoolss_PrinterInfo7 *r) { - fstring guid = ""; - rpcstr_pull(guid, i7->guid.buffer,sizeof(guid), -1, STR_TERMINATE); - printf("\tguid:[%s]\n", guid); - printf("\taction:[0x%x]\n", i7->action); + printf("\tguid:[%s]\n", r->guid); + printf("\taction:[0x%x]\n", r->action); } @@ -469,10 +467,14 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 info_level = 2; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; const char *printername, *comment = NULL; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; if (argc == 1 || argc > 3) { printf("Usage: %s printername comment\n", argv[0]); @@ -485,6 +487,9 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, comment = argv[2]; } + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); /* get a printer handle */ @@ -498,18 +503,28 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, opened_hnd = True; /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Modify the comment. */ - init_unistr(&ctr.printers_2->comment, comment); - ctr.printers_2->devmode = NULL; - ctr.printers_2->secdesc = NULL; + info.info2.comment = comment; - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0); + info_ctr.level = 2; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (W_ERROR_IS_OK(result)) printf("Success in setting comment.\n"); @@ -529,11 +544,18 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 info_level = 2; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; const char *printername, *new_printername = NULL; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); if (argc == 1 || argc > 3) { printf("Usage: %s printername new_printername\n", argv[0]); @@ -559,17 +581,29 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, opened_hnd = True; /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Modify the printername. */ - init_unistr(&ctr.printers_2->printername, new_printername); - ctr.printers_2->devmode = NULL; - ctr.printers_2->secdesc = NULL; - - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0); + info.info2.printername = new_printername; + info.info2.devmode = NULL; + info.info2.secdesc = NULL; + + info_ctr.level = info_level; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (W_ERROR_IS_OK(result)) printf("Success in setting printername.\n"); @@ -591,8 +625,8 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, WERROR result; uint32 info_level = 1; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; const char *printername; + union spoolss_PrinterInfo info; if (argc == 1 || argc > 3) { printf("Usage: %s [level]\n", argv[0]); @@ -619,14 +653,17 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Display printer info */ - switch (info_level) { +#if 0 /* FIXME GD */ case 0: display_print_info_0(ctr.printers_0); break; @@ -639,14 +676,14 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, case 3: display_print_info_3(ctr.printers_3); break; +#endif case 7: - display_print_info_7(ctr.printers_7); + display_print_info7(&info.info7); break; default: printf("unknown info level %d\n", info_level); break; } - done: if (opened_hnd) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); @@ -1570,11 +1607,17 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 level = 2; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; - PRINTER_INFO_2 info2; const char *printername; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); /* parse the command arguments */ if (argc != 3) @@ -1598,11 +1641,11 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, /* Get printer info */ - ZERO_STRUCT (info2); - ctr.printers_2 = &info2; - - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + level, + 0, + &info); if (!W_ERROR_IS_OK(result)) { printf ("Unable to retrieve printer information!\n"); goto done; @@ -1610,10 +1653,17 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, /* Set the printer driver */ - init_unistr(&ctr.printers_2->drivername, argv[2]); - - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0); - + info.info2.drivername = argv[2]; + info_ctr.level = 2; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (!W_ERROR_IS_OK(result)) { printf("SetPrinter call failed!\n"); goto done;; @@ -2167,8 +2217,7 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, const char *printername; POLICY_HND pol; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; - PRINTER_INFO_0 info; + union spoolss_PrinterInfo info; REGISTRY_VALUE value; TALLOC_CTX *tmp_ctx = talloc_stackframe(); @@ -2218,15 +2267,16 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, opened_hnd = True; - ctr.printers_0 = &info; - - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + 0, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; printf("%s\n", current_timestring(tmp_ctx, True)); - printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id); + printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id); /* Set the printer data */ @@ -2306,13 +2356,16 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, } printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]); - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + 0, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; printf("%s\n", current_timestring(tmp_ctx, True)); - printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id); + printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id); done: /* cleanup */ @@ -2706,12 +2759,16 @@ done: static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, struct rpc_pipe_client *cli2, POLICY_HND *hnd2 ) { - PRINTER_INFO_CTR ctr1, ctr2; + union spoolss_PrinterInfo info1, info2; WERROR werror; TALLOC_CTX *mem_ctx = talloc_init("compare_printer"); printf("Retrieving printer propertiesfor %s...", cli1->desthost); - werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1); + werror = rpccli_spoolss_getprinter(cli1, mem_ctx, + hnd1, + 2, + 0, + &info1); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); @@ -2720,7 +2777,11 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, printf("ok\n"); printf("Retrieving printer properties for %s...", cli2->desthost); - werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2); + werror = rpccli_spoolss_getprinter(cli2, mem_ctx, + hnd2, + 2, + 0, + &info2); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); @@ -2739,7 +2800,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, struct rpc_pipe_client *cli2, POLICY_HND *hnd2 ) { - PRINTER_INFO_CTR ctr1, ctr2; + union spoolss_PrinterInfo info1, info2; WERROR werror; TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc"); SEC_DESC *sd1, *sd2; @@ -2747,7 +2808,11 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("Retrieving printer security for %s...", cli1->desthost); - werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1); + werror = rpccli_spoolss_getprinter(cli1, mem_ctx, + hnd1, + 3, + 0, + &info1); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); result = False; @@ -2756,7 +2821,11 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("ok\n"); printf("Retrieving printer security for %s...", cli2->desthost); - werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2); + werror = rpccli_spoolss_getprinter(cli2, mem_ctx, + hnd2, + 3, + 0, + &info2); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); result = False; @@ -2767,14 +2836,8 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("++ "); - if ( (ctr1.printers_3 != ctr2.printers_3) && (!ctr1.printers_3 || !ctr2.printers_3) ) { - printf("NULL PRINTER_INFO_3!\n"); - result = False; - goto done; - } - - sd1 = ctr1.printers_3->secdesc; - sd2 = ctr2.printers_3->secdesc; + sd1 = info1.info3.secdesc; + sd2 = info2.info3.secdesc; if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) { printf("NULL secdesc!\n"); -- cgit From f8af5130d5515e017330a2123b933109599e072c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 10:58:53 +0100 Subject: s3-net: use rpccli_spoolss_getprinter and rpccli_spoolss_SetPrinter. Guenther --- source3/utils/net_rpc_printer.c | 169 +++++++++++++++++++++++++++++----------- 1 file changed, 123 insertions(+), 46 deletions(-) diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 17df69597f..0f21e1758b 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -775,13 +775,16 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, - PRINTER_INFO_CTR *ctr) + union spoolss_PrinterInfo *info) { WERROR result; /* getprinter call */ - result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, hnd, level, ctr); - + result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, + hnd, + level, + 0, /* offered */ + info); if (!W_ERROR_IS_OK(result)) { printf("cannot get printer-info: %s\n", win_errstr(result)); return false; @@ -794,12 +797,64 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, - PRINTER_INFO_CTR *ctr) + union spoolss_PrinterInfo *info) { WERROR result; + NTSTATUS status; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); /* setprinter call */ - result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, hnd, level, ctr, 0); + + info_ctr.level = level; + switch (level) { + case 0: + info_ctr.info.info0 = (struct spoolss_SetPrinterInfo0 *)&info->info0; + break; + case 1: + info_ctr.info.info1 = (struct spoolss_SetPrinterInfo1 *)&info->info1; + break; + case 2: + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info->info2; + break; + case 3: + info_ctr.info.info3 = (struct spoolss_SetPrinterInfo3 *)&info->info3; + break; + case 4: + info_ctr.info.info4 = (struct spoolss_SetPrinterInfo4 *)&info->info4; + break; + case 5: + info_ctr.info.info5 = (struct spoolss_SetPrinterInfo5 *)&info->info5; + break; + case 6: + info_ctr.info.info6 = (struct spoolss_SetPrinterInfo6 *)&info->info6; + break; + case 7: + info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info->info7; + break; +#if 0 /* FIXME GD */ + case 8: + info_ctr.info.info8 = (struct spoolss_SetPrinterInfo8 *)&info->info8; + break; + case 9: + info_ctr.info.info9 = (struct spoolss_SetPrinterInfo9 *)&info->info9; + break; +#endif + default: + break; /* FIXME */ + } + + status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx, + hnd, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (!W_ERROR_IS_OK(result)) { printf("cannot set printer-info: %s\n", win_errstr(result)); @@ -1027,6 +1082,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, { POLICY_HND hnd; + union spoolss_PrinterInfo info; /* no arguments given, enumerate all printers */ if (argc == 0) { @@ -1039,6 +1095,8 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, goto out; } + /* FIXME GD */ + return false; /* argument given, get a single printer by name */ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0], @@ -1047,7 +1105,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, &hnd)) return false; - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, ctr)) { + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return false; } @@ -1216,7 +1274,11 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ uint32 i, num_printers; uint32 level = 7; char *printername, *sharename; - PRINTER_INFO_CTR ctr, ctr_pub; + PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; POLICY_HND hnd; bool got_hnd = false; WERROR result; @@ -1249,7 +1311,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ got_hnd = true; /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; /* check action and set string */ @@ -1269,9 +1331,21 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ break; } - ctr_pub.printers_7->action = action; + info.info7.action = action; + info_ctr.level = 7; + info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info.info7; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + + nt_status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx, + &hnd, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); - result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub, 0); if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) { printf("cannot set printer-info: %s\n", win_errstr(result)); goto done; @@ -1355,8 +1429,8 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, uint32 i, num_printers; uint32 level = 7; char *printername, *sharename; - char *guid; PRINTER_INFO_CTR ctr, ctr_pub; + union spoolss_PrinterInfo info; POLICY_HND hnd; bool got_hnd = false; int state; @@ -1390,23 +1464,18 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, got_hnd = true; /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; - rpcstr_pull_talloc(mem_ctx, - &guid, - ctr_pub.printers_7->guid.buffer, - -1, - STR_TERMINATE); - if (!guid) { + if (!info.info7.guid) { goto done; } - state = ctr_pub.printers_7->action; + state = info.info7.action; switch (state) { case SPOOL_DS_PUBLISH: printf("printer [%s] is published", sharename); if (c->opt_verbose) - printf(", guid: %s", guid); + printf(", guid: %s", info.info7.guid); printf("\n"); break; case SPOOL_DS_UNPUBLISH: @@ -1468,8 +1537,9 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum; + PRINTER_INFO_CTR ctr_src, ctr_enum; struct cli_state *cli_dst = NULL; + union spoolss_PrinterInfo info_src, info_dst; ZERO_STRUCT(ctr_src); @@ -1540,23 +1610,23 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, got_hnd_dst = true; /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; /* check for existing src printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &ctr_src)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &info_src)) goto done; /* Copy Security Descriptor */ /* copy secdesc (info level 2) */ - ctr_dst.printers_2->devmode = NULL; - ctr_dst.printers_2->secdesc = dup_sec_desc(mem_ctx, ctr_src.printers_3->secdesc); + info_dst.info2.devmode = NULL; + info_dst.info2.secdesc = dup_sec_desc(mem_ctx, info_src.info3.secdesc); if (c->opt_verbose) - display_sec_desc(ctr_dst.printers_2->secdesc); + display_sec_desc(info_dst.info2.secdesc); - if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &ctr_dst)) + if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) goto done; DEBUGADD(1,("\tSetPrinter of SECDESC succeeded\n")); @@ -1629,7 +1699,8 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_enum, ctr_dst; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst; uint32 num_forms; FORM_1 *forms; struct cli_state *cli_dst = NULL; @@ -1698,7 +1769,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; /* finally migrate forms */ @@ -1824,6 +1895,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, POLICY_HND hnd_src, hnd_dst; union spoolss_DriverInfo drv_info_src; PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst; + union spoolss_PrinterInfo info_dst; struct cli_state *cli_dst = NULL; struct cli_state *cli_share_src = NULL; struct cli_state *cli_share_dst = NULL; @@ -1903,7 +1975,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, got_hnd_dst = true; /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) goto done; @@ -1965,9 +2037,9 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, } /* setdriver dst */ - init_unistr(&info_ctr_dst.printers_2->drivername, drivername); + info_dst.info2.drivername = drivername; - if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) { + if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -2043,7 +2115,8 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i = 0, num_printers; uint32 level = 2; - PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst, info_src; struct cli_state *cli_dst = NULL; POLICY_HND hnd_dst, hnd_src; char *printername, *sharename; @@ -2105,7 +2178,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, } /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) { + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) { printf ("could not get printer, creating printer.\n"); } else { DEBUG(1,("printer already exists: %s\n", sharename)); @@ -2128,7 +2201,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, got_hnd_src = true; /* getprinter on the src server */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &ctr_src)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &info_src)) goto done; /* copy each src printer to a dst printer 1:1, @@ -2212,7 +2285,8 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_enum, ctr_dst, ctr_dst_publish; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst_publish, info_dst; REGVAL_CTR *reg_ctr; struct cli_state *cli_dst = NULL; char *devicename = NULL, *unc_name = NULL, *url = NULL; @@ -2221,6 +2295,8 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, uint16 *keylist = NULL, *curkey; ZERO_STRUCT(ctr_enum); + /* FIXME GD */ + ZERO_STRUCT(info_dst_publish); DEBUG(3,("copying printer settings\n")); @@ -2293,31 +2369,32 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, - level, &ctr_dst)) + level, &info_dst)) goto done; +#if 0 /* FIXME GD */ /* STEP 1: COPY DEVICE-MODE and other PRINTER_INFO_2-attributes */ - ctr_dst.printers_2 = &ctr_enum.printers_2[i]; + info_dst.info2 = &ctr_enum.printers_2[i]; /* why is the port always disconnected when the printer is correctly installed (incl. driver ???) */ - init_unistr( &ctr_dst.printers_2->portname, SAMBA_PRINTER_PORT_NAME); + info_dst.info2.portname = SAMBA_PRINTER_PORT_NAME; /* check if printer is published */ if (ctr_enum.printers_2[i].attributes & PRINTER_ATTRIBUTE_PUBLISHED) { /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish)) goto done; - ctr_dst_publish.printers_7->action = SPOOL_DS_PUBLISH; + info_dst_publish.info7.action = SPOOL_DS_PUBLISH; /* ignore false from setprinter due to WERR_IO_PENDING */ - net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish); + net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish); DEBUG(3,("republished printer\n")); } @@ -2325,14 +2402,14 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, if (ctr_enum.printers_2[i].devmode != NULL) { /* copy devmode (info level 2) */ - ctr_dst.printers_2->devmode = (DEVICEMODE *) + info_dst.info2.devmode = (DEVICEMODE *) TALLOC_MEMDUP(mem_ctx, ctr_enum.printers_2[i].devmode, sizeof(DEVICEMODE)); /* do not copy security descriptor (we have another * command for that) */ - ctr_dst.printers_2->secdesc = NULL; + info_dst.info2.secdesc = NULL; #if 0 if (asprintf(&devicename, "\\\\%s\\%s", longname, @@ -2345,12 +2422,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, devicename); #endif if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, - level, &ctr_dst)) + level, &info_dst)) goto done; DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n")); } - +#endif /* STEP 2: COPY REGISTRY VALUES */ /* please keep in mind that samba parse_spools gives horribly -- cgit From 109ba07b0e2ce45cc0a960bcafd0e8d28c877ae3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 01:11:01 +0100 Subject: s3-spoolss: use rpccli_spoolss_addprinterex wrapper. Guenther --- source3/rpcclient/cmd_spoolss.c | 29 ++--------------------------- source3/utils/net_rpc_printer.c | 9 ++++++++- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 4e1c7f1422..ba01f7aa8b 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1526,14 +1526,8 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, int argc, const char **argv) { WERROR result; - NTSTATUS status; struct spoolss_SetPrinterInfoCtr info_ctr; struct spoolss_SetPrinterInfo2 info2; - struct policy_handle handle; - struct spoolss_DevmodeContainer devmode_ctr; - struct sec_desc_buf sd; - struct spoolss_UserLevelCtr userlevel_ctr; - struct spoolss_UserLevel1 level1; /* parse the command arguments */ if (argc != 5) @@ -1543,9 +1537,7 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, } /* Fill in the DRIVER_INFO_2 struct */ - ZERO_STRUCT(devmode_ctr); ZERO_STRUCT(info2); - ZERO_STRUCT(sd); info2.printername = argv[1]; info2.drivername = argv[3]; @@ -1573,25 +1565,8 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, info_ctr.level = 2; info_ctr.info.info2 = &info2; - level1.size = 28; /* wild guess */ - level1.build = 1381; - level1.major = 2; - level1.minor = 0; - level1.processor = 0; - level1.client = global_myname(); - level1.user = cli->auth->user_name; - - userlevel_ctr.level = 1; - userlevel_ctr.user_info.level1 = &level1; - - status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx, - cli->srv_name_slash, - &info_ctr, - &devmode_ctr, - &sd, - &userlevel_ctr, - &handle, - &result); + result = rpccli_spoolss_addprinterex(cli, mem_ctx, + &info_ctr); if (W_ERROR_IS_OK(result)) printf ("Printer %s successfully installed.\n", argv[1]); diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 0f21e1758b..f4dd824c84 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -2123,6 +2123,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, bool got_hnd_src = false; bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; + struct spoolss_SetPrinterInfoCtr info_ctr; DEBUG(3,("copying printers\n")); @@ -2207,7 +2208,13 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, /* copy each src printer to a dst printer 1:1, maybe some values have to be changed though */ d_printf("creating printer: %s\n", printername); - result = rpccli_spoolss_addprinterex (pipe_hnd_dst, mem_ctx, level, &ctr_src); + + info_ctr.level = level; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info_src.info2; + + result = rpccli_spoolss_addprinterex(pipe_hnd_dst, + mem_ctx, + &info_ctr); if (W_ERROR_IS_OK(result)) d_printf ("printer [%s] successfully added.\n", printername); -- cgit From c7ba20b465e4c2bf893891ab7ace8172704bb27c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 10 Feb 2009 23:37:00 +0100 Subject: s3-spoolss: remove rpccli_spoolss_addprinterex. Guenther --- source3/include/proto.h | 9 -- source3/include/rpc_spoolss.h | 34 ------ source3/rpc_client/cli_spoolss.c | 35 ------ source3/rpc_parse/parse_spoolss.c | 221 -------------------------------------- 4 files changed, 299 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9ed8901fb3..4691dc70ec 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5501,8 +5501,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, uint32 level, const char *env, uint32 *num_drivers, PRINTER_DRIVER_CTR *ctr); -WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr); WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *handle, int level, uint32 *num_forms, FORM_1 **forms); @@ -5813,11 +5811,7 @@ bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); -bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u ); bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode); -bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, - const char *srv_name, const char* clientname, const char* user_name, - uint32 level, PRINTER_INFO_CTR *ctr); bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, PRINTER_INFO_2 *info); bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, @@ -5930,9 +5924,6 @@ bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth); bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth); bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth); -bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, - prs_struct *ps, int depth); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, NT_PRINTER_INFO_LEVEL_2 *d); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 48609a3cd6..65fab7d319 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -261,25 +261,6 @@ PRINTER_MESSAGE_INFO; #define DRIVER_MAX_VERSION 4 -/* this struct is undocumented */ -/* thanks to the ddk ... */ -typedef struct { - uint32 size; /* length of user_name & client_name + 2? */ - UNISTR2 *client_name; - UNISTR2 *user_name; - uint32 build; - uint32 major; - uint32 minor; - uint32 processor; -} SPOOL_USER_1; - -typedef struct { - uint32 level; - union { - SPOOL_USER_1 *user1; - } user; -} SPOOL_USER_CTR; - /* * Devicemode structure */ @@ -966,21 +947,6 @@ SPOOL_R_SETPRINTER; /********************************************/ -typedef struct { - UNISTR2 *server_name; - uint32 level; - SPOOL_PRINTER_INFO_LEVEL info; - DEVMODE_CTR devmode_ctr; - SEC_DESC_BUF *secdesc_ctr; - uint32 user_switch; - SPOOL_USER_CTR user_ctr; -} SPOOL_Q_ADDPRINTEREX; - -typedef struct { - POLICY_HND handle; - WERROR status; -} SPOOL_R_ADDPRINTEREX; - typedef struct spool_q_enumprintprocessors { uint32 name_ptr; diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 4fe05a5ff4..b063a33ca6 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -977,41 +977,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTEREX in; - SPOOL_R_ADDPRINTEREX out; - fstring server, client, user; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - slprintf(client, sizeof(fstring)-1, "\\\\%s", global_myname()); - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - - strupper_m(client); - strupper_m(server); - - fstrcpy (user, cli->auth->user_name); - - make_spoolss_q_addprinterex( mem_ctx, &in, server, client, - user, level, ctr); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTEREX, - in, out, - qbuf, rbuf, - spoolss_io_q_addprinterex, - spoolss_io_r_addprinterex, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *handle, int level, uint32 *num_forms, FORM_1 **forms) diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 12c7af49cf..4bf831c53d 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -70,78 +70,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) return True; } -/******************************************************************* -********************************************************************/ - -bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u ) -{ - prs_debug(ps, depth, desc, ""); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("size", ps, depth, &q_u->size)) - return False; - - if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name)) - return False; - if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name)) - return False; - - if (!prs_uint32("build", ps, depth, &q_u->build)) - return False; - if (!prs_uint32("major", ps, depth, &q_u->major)) - return False; - if (!prs_uint32("minor", ps, depth, &q_u->minor)) - return False; - if (!prs_uint32("processor", ps, depth, &q_u->processor)) - return False; - - if (!prs_io_unistr2("", ps, depth, q_u->client_name)) - return False; - if (!prs_align(ps)) - return False; - - if (!prs_io_unistr2("", ps, depth, q_u->user_name)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth) -{ - if (q_u==NULL) - return False; - - prs_debug(ps, depth, desc, "spool_io_user_level"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - switch ( q_u->level ) - { - case 1: - if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, - sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) - { - return False; - } - break; - default: - return False; - } - - return True; -} - /******************************************************************* * read or write a DEVICEMODE struct. * on reading allocate memory for the private member @@ -376,72 +304,6 @@ static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_str return True; } -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, - const char *srv_name, const char* clientname, const char* user_name, - uint32 level, PRINTER_INFO_CTR *ctr) -{ - DEBUG(5,("make_spoolss_q_addprinterex\n")); - - if (!ctr || !ctr->printers_2) - return False; - - ZERO_STRUCTP(q_u); - - q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->server_name) { - return False; - } - init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE); - - q_u->level = level; - - q_u->info.level = level; - q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0; - switch (level) { - case 2: - /* init q_u->info.info2 from *info */ - if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) { - DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n")); - return False; - } - break; - default : - break; - } - - q_u->user_switch=1; - - q_u->user_ctr.level = 1; - q_u->user_ctr.user.user1 = TALLOC_P( talloc_tos(), SPOOL_USER_1 ); - if (!q_u->user_ctr.user.user1) { - return False; - } - q_u->user_ctr.user.user1->build = 1381; - q_u->user_ctr.user.user1->major = 2; - q_u->user_ctr.user.user1->minor = 0; - q_u->user_ctr.user.user1->processor = 0; - - q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->user_ctr.user.user1->client_name) { - return False; - } - q_u->user_ctr.user.user1->user_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->user_ctr.user.user1->user_name) { - return False; - } - init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE); - init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE); - - q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len + - q_u->user_ctr.user.user1->client_name->uni_str_len + 2; - - return True; -} - /******************************************************************* create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct *******************************************************************/ @@ -3017,89 +2879,6 @@ bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, return True; } -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth) -{ - uint32 ptr_sec_desc = 0; - - prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name)) - return False; - if (!prs_io_unistr2("servername", ps, depth, q_u->server_name)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("info_level", ps, depth, &q_u->level)) - return False; - - if(!spool_io_printer_info_level("", &q_u->info, ps, depth)) - return False; - - if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - switch (q_u->level) { - case 2: - ptr_sec_desc = q_u->info.info_2->secdesc_ptr; - break; - case 3: - ptr_sec_desc = q_u->info.info_3->secdesc_ptr; - break; - } - if (ptr_sec_desc) { - if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth)) - return False; - } else { - uint32 dummy = 0; - - /* Parse a NULL security descriptor. This should really - happen inside the sec_io_desc_buf() function. */ - - prs_debug(ps, depth, "", "sec_io_desc_buf"); - if (!prs_uint32("size", ps, depth + 1, &dummy)) - return False; - if (!prs_uint32("ptr", ps, depth + 1, &dummy)) - return False; - } - - if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch)) - return False; - if(!spool_io_user_level("", &q_u->user_ctr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex"); - depth++; - - if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - /******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ -- cgit From c03f2072762d91240fe90a2f02542e521313e7ef Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 00:12:58 +0100 Subject: s3-spoolss: remove rpccli_spoolss_setprinter. Guenther --- source3/include/proto.h | 21 -- source3/include/rpc_spoolss.h | 92 ------ source3/rpc_client/cli_spoolss.c | 26 -- source3/rpc_parse/parse_spoolss.c | 585 -------------------------------------- 4 files changed, 724 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 4691dc70ec..d6ec7013cf 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5493,9 +5493,6 @@ WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr); -WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command); WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, @@ -5812,12 +5809,6 @@ bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode); -bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, - PRINTER_INFO_2 *info); -bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, - PRINTER_INFO_3 *info); -bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, - PRINTER_INFO_7 *info); bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, const POLICY_HND *handle, const char *valuename, uint32 size); @@ -5895,11 +5886,6 @@ bool make_spoolss_q_getprinter( RPC_BUFFER *buffer, uint32 offered ); -bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, - const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, - uint32 command); -bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth); bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, uint32 firstjob, @@ -5919,14 +5905,7 @@ bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth); bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth); bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth); -bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); -bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, - NT_PRINTER_INFO_LEVEL_2 *d); bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 65fab7d319..c494fdd6bf 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -853,98 +853,6 @@ typedef struct spool_r_enumforms } SPOOL_R_ENUMFORMS; -typedef struct spool_printer_info_level_1 -{ - uint32 flags; - uint32 description_ptr; - uint32 name_ptr; - uint32 comment_ptr; - UNISTR2 description; - UNISTR2 name; - UNISTR2 comment; -} SPOOL_PRINTER_INFO_LEVEL_1; - -typedef struct spool_printer_info_level_2 -{ - uint32 servername_ptr; - uint32 printername_ptr; - uint32 sharename_ptr; - uint32 portname_ptr; - uint32 drivername_ptr; - uint32 comment_ptr; - uint32 location_ptr; - uint32 devmode_ptr; - uint32 sepfile_ptr; - uint32 printprocessor_ptr; - uint32 datatype_ptr; - uint32 parameters_ptr; - uint32 secdesc_ptr; - uint32 attributes; - uint32 priority; - uint32 default_priority; - uint32 starttime; - uint32 untiltime; - uint32 status; - uint32 cjobs; - uint32 averageppm; - UNISTR2 servername; - UNISTR2 printername; - UNISTR2 sharename; - UNISTR2 portname; - UNISTR2 drivername; - UNISTR2 comment; - UNISTR2 location; - UNISTR2 sepfile; - UNISTR2 printprocessor; - UNISTR2 datatype; - UNISTR2 parameters; -} -SPOOL_PRINTER_INFO_LEVEL_2; - -typedef struct spool_printer_info_level_3 -{ - uint32 secdesc_ptr; -} -SPOOL_PRINTER_INFO_LEVEL_3; - -typedef struct spool_printer_info_level_7 -{ - uint32 guid_ptr; - uint32 action; - UNISTR2 guid; -} -SPOOL_PRINTER_INFO_LEVEL_7; - -typedef struct spool_printer_info_level -{ - uint32 level; - uint32 info_ptr; - SPOOL_PRINTER_INFO_LEVEL_1 *info_1; - SPOOL_PRINTER_INFO_LEVEL_2 *info_2; - SPOOL_PRINTER_INFO_LEVEL_3 *info_3; - SPOOL_PRINTER_INFO_LEVEL_7 *info_7; -} -SPOOL_PRINTER_INFO_LEVEL; - -typedef struct spool_q_setprinter -{ - POLICY_HND handle; - uint32 level; - SPOOL_PRINTER_INFO_LEVEL info; - SEC_DESC_BUF *secdesc_ctr; - DEVMODE_CTR devmode_ctr; - - uint32 command; - -} -SPOOL_Q_SETPRINTER; - -typedef struct spool_r_setprinter -{ - WERROR status; -} -SPOOL_R_SETPRINTER; - /********************************************/ typedef struct spool_q_enumprintprocessors diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index b063a33ca6..3986766e43 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -866,32 +866,6 @@ WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTER in; - SPOOL_R_SETPRINTER out; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_setprinter, - spoolss_io_r_setprinter, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 4bf831c53d..d749d2ef9b 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -258,154 +258,6 @@ bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE return True; } -/******************************************************************* - Read or write a DEVICEMODE container -********************************************************************/ - -static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth) -{ - if (dm_c==NULL) - return False; - - prs_debug(ps, depth, desc, "spoolss_io_devmode_cont"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_uint32("size", ps, depth, &dm_c->size)) - return False; - - if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr)) - return False; - - if (dm_c->size==0 || dm_c->devmode_ptr==0) { - if (UNMARSHALLING(ps)) - /* if while reading there is no DEVMODE ... */ - dm_c->devmode=NULL; - return True; - } - - /* so we have a DEVICEMODE to follow */ - if (UNMARSHALLING(ps)) { - DEBUG(9,("Allocating memory for spoolss_io_devmode\n")); - dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1); - if(dm_c->devmode == NULL) - return False; - } - - /* this is bad code, shouldn't be there */ - if (!prs_uint32("size", ps, depth, &dm_c->size)) - return False; - - if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode)) - return False; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct -*******************************************************************/ - -bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, - PRINTER_INFO_2 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_2 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) { - DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n")); - return False; - } - - inf->servername_ptr = (info->servername.buffer!=NULL)?1:0; - inf->printername_ptr = (info->printername.buffer!=NULL)?1:0; - inf->sharename_ptr = (info->sharename.buffer!=NULL)?1:0; - inf->portname_ptr = (info->portname.buffer!=NULL)?1:0; - inf->drivername_ptr = (info->drivername.buffer!=NULL)?1:0; - inf->comment_ptr = (info->comment.buffer!=NULL)?1:0; - inf->location_ptr = (info->location.buffer!=NULL)?1:0; - inf->devmode_ptr = (info->devmode!=NULL)?1:0; - inf->sepfile_ptr = (info->sepfile.buffer!=NULL)?1:0; - inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0; - inf->datatype_ptr = (info->datatype.buffer!=NULL)?1:0; - inf->parameters_ptr = (info->parameters.buffer!=NULL)?1:0; - inf->secdesc_ptr = (info->secdesc!=NULL)?1:0; - inf->attributes = info->attributes; - inf->priority = info->priority; - inf->default_priority = info->defaultpriority; - inf->starttime = info->starttime; - inf->untiltime = info->untiltime; - inf->cjobs = info->cjobs; - inf->averageppm = info->averageppm; - init_unistr2_from_unistr(inf, &inf->servername, &info->servername); - init_unistr2_from_unistr(inf, &inf->printername, &info->printername); - init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename); - init_unistr2_from_unistr(inf, &inf->portname, &info->portname); - init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername); - init_unistr2_from_unistr(inf, &inf->comment, &info->comment); - init_unistr2_from_unistr(inf, &inf->location, &info->location); - init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile); - init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor); - init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype); - init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters); - init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype); - - *spool_info2 = inf; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct -*******************************************************************/ - -bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, - PRINTER_INFO_3 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_3 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) { - DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n")); - return False; - } - - inf->secdesc_ptr = (info->secdesc!=NULL)?1:0; - - *spool_info3 = inf; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct -*******************************************************************/ - -bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, - PRINTER_INFO_7 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_7 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) { - DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n")); - return False; - } - - inf->guid_ptr = (info->guid.buffer!=NULL)?1:0; - inf->action = info->action; - init_unistr2_from_unistr(inf, &inf->guid, &info->guid); - - *spool_info7 = inf; - - return True; -} - /******************************************************************* * make a structure. ********************************************************************/ @@ -2178,185 +2030,6 @@ bool make_spoolss_q_getprinter( return True; } -/******************************************************************* - * init a structure. - ********************************************************************/ -bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, - const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, - uint32 command) -{ - SEC_DESC *secdesc; - DEVICEMODE *devmode; - - if (!q_u || !info) - return False; - - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - q_u->level = level; - q_u->info.level = level; - q_u->info.info_ptr = 1; /* Info is != NULL, see above */ - switch (level) { - - /* There's no such thing as a setprinter level 1 */ - - case 2: - secdesc = info->printers_2->secdesc; - devmode = info->printers_2->devmode; - - make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2); -#if 1 /* JERRY TEST */ - q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF); - if (!q_u->secdesc_ctr) - return False; - q_u->secdesc_ctr->sd = secdesc; - q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0; - - q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0; - q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0; - q_u->devmode_ctr.devmode = devmode; -#else - q_u->secdesc_ctr = NULL; - - q_u->devmode_ctr.devmode_ptr = 0; - q_u->devmode_ctr.size = 0; - q_u->devmode_ctr.devmode = NULL; -#endif - break; - case 3: - secdesc = info->printers_3->secdesc; - - make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3); - - q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF); - if (!q_u->secdesc_ctr) - return False; - q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0; - q_u->secdesc_ctr->sd = secdesc; - - break; - case 7: - make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7); - break; - - default: - DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level)); - break; - } - - - q_u->command = command; - - return True; -} - - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_setprinter"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - Marshall/unmarshall a SPOOL_Q_SETPRINTER struct. -********************************************************************/ - -bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth) -{ - uint32 ptr_sec_desc = 0; - - prs_debug(ps, depth, desc, "spoolss_io_q_setprinter"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth)) - return False; - if(!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - /* check for supported levels and structures we know about */ - - switch ( q_u->level ) { - case 0: - case 2: - case 3: - case 7: - /* supported levels */ - break; - default: - DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", - q_u->level)); - return True; - } - - - if(!spool_io_printer_info_level("", &q_u->info, ps, depth)) - return False; - - if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - switch (q_u->level) - { - case 2: - { - ptr_sec_desc = q_u->info.info_2->secdesc_ptr; - break; - } - case 3: - { - /* FIXME ! Our parsing here is wrong I think, - * but for a level3 it makes no sense for - * ptr_sec_desc to be NULL. JRA. Based on - * a Vista sniff from Martin Zielinski . - */ - if (UNMARSHALLING(ps)) { - ptr_sec_desc = 1; - } else { - ptr_sec_desc = q_u->info.info_3->secdesc_ptr; - } - break; - } - } - if (ptr_sec_desc) - { - if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth)) - return False; - } else { - uint32 dummy = 0; - - /* Parse a NULL security descriptor. This should really - happen inside the sec_io_desc_buf() function. */ - - prs_debug(ps, depth, "", "sec_io_desc_buf"); - if (!prs_uint32("size", ps, depth + 1, &dummy)) - return False; - if (!prs_uint32("ptr", ps, depth + 1, &dummy)) - return False; - } - - if(!prs_uint32("command", ps, depth, &q_u->command)) - return False; - - return True; -} - /******************************************************************* ********************************************************************/ @@ -2652,233 +2325,6 @@ bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct return True; } -/******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure. -********************************************************************/ - -bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_1"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("flags", ps, depth, &il->flags)) - return False; - if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr)) - return False; - if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr)) - return False; - if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr)) - return False; - - if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure. -********************************************************************/ - -bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure. -********************************************************************/ - -bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr)) - return False; - if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr)) - return False; - if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr)) - return False; - if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr)) - return False; - - if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr)) - return False; - if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr)) - return False; - if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr)) - return False; - if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr)) - return False; - if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr)) - return False; - if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr)) - return False; - if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr)) - return False; - if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr)) - return False; - if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr)) - return False; - - if(!prs_uint32("attributes", ps, depth, &il->attributes)) - return False; - if(!prs_uint32("priority", ps, depth, &il->priority)) - return False; - if(!prs_uint32("default_priority", ps, depth, &il->default_priority)) - return False; - if(!prs_uint32("starttime", ps, depth, &il->starttime)) - return False; - if(!prs_uint32("untiltime", ps, depth, &il->untiltime)) - return False; - if(!prs_uint32("status", ps, depth, &il->status)) - return False; - if(!prs_uint32("cjobs", ps, depth, &il->cjobs)) - return False; - if(!prs_uint32("averageppm", ps, depth, &il->averageppm)) - return False; - - if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth)) - return False; - - return True; -} - -bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_7"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr)) - return False; - if(!prs_uint32("action", ps, depth, &il->action)) - return False; - - if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth)) - return False; - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("level", ps, depth, &il->level)) - return False; - if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr)) - return False; - - /* if no struct inside just return */ - if (il->info_ptr==0) { - if (UNMARSHALLING(ps)) { - il->info_1=NULL; - il->info_2=NULL; - } - return True; - } - - switch (il->level) { - /* - * level 0 is used by setprinter when managing the queue - * (hold, stop, start a queue) - */ - case 0: - break; - /* DOCUMENT ME!!! What is level 1 used for? */ - case 1: - { - if (UNMARSHALLING(ps)) { - if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_1("", il->info_1, ps, depth)) - return False; - break; - } - /* - * level 2 is used by addprinter - * and by setprinter when updating printer's info - */ - case 2: - if (UNMARSHALLING(ps)) { - if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_2("", il->info_2, ps, depth)) - return False; - break; - /* DOCUMENT ME!!! What is level 3 used for? */ - case 3: - { - if (UNMARSHALLING(ps)) { - if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_3("", il->info_3, ps, depth)) - return False; - break; - } - case 7: - if (UNMARSHALLING(ps)) - if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL) - return False; - if (!spool_io_printer_info_level_7("", il->info_7, ps, depth)) - return False; - break; - } - - return True; -} - /******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ @@ -2903,37 +2349,6 @@ bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 return True; } -/******************************************************************* - ********************************************************************/ - -bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, - NT_PRINTER_INFO_LEVEL_2 *d) -{ - DEBUG(7,("Converting from UNICODE to ASCII\n")); - - d->attributes=uni->attributes; - d->priority=uni->priority; - d->default_priority=uni->default_priority; - d->starttime=uni->starttime; - d->untiltime=uni->untiltime; - d->status=uni->status; - d->cjobs=uni->cjobs; - - unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)); - unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)); - unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)); - unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)); - unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)); - unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)); - unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)); - unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)); - unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)); - unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)); - unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)); - - return True; -} - /******************************************************************* ********************************************************************/ -- cgit From 59e90d3715a577503434ace9e01bfe63dfcfa714 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 01:23:40 +0100 Subject: s3-spoolss: remove rpccli_spoolss_getprinter. Guenther --- source3/include/proto.h | 11 ----- source3/rpc_client/cli_spoolss.c | 84 --------------------------------------- source3/rpc_parse/parse_spoolss.c | 26 ------------ 3 files changed, 121 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d6ec7013cf..8084111145 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5490,9 +5490,6 @@ WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem uint32 *num_printers, PRINTER_INFO_CTR *ctr); WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr); -WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr); WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, @@ -5878,14 +5875,6 @@ bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_ bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth); bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth); bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); -bool make_spoolss_q_getprinter( - TALLOC_CTX *mem_ctx, - SPOOL_Q_GETPRINTER *q_u, - const POLICY_HND *hnd, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered -); bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, uint32 firstjob, diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 3986766e43..c9d23efdf2 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -782,90 +782,6 @@ WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTER in; - SPOOL_R_GETPRINTER out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - /* Initialise input parameters */ - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinter, - spoolss_io_r_getprinter, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinter, - spoolss_io_r_getprinter, - WERR_GENERAL_FAILURE ); - } - - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - switch (level) { - case 0: - if (!decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0)) { - return WERR_GENERAL_FAILURE; - } - break; - case 1: - if (!decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 3: - if (!decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3)) { - return WERR_GENERAL_FAILURE; - } - break; - case 7: - if (!decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index d749d2ef9b..c9c897253a 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -2004,32 +2004,6 @@ bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_stru return True; } -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_getprinter( - TALLOC_CTX *mem_ctx, - SPOOL_Q_GETPRINTER *q_u, - const POLICY_HND *hnd, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered -) -{ - if (q_u == NULL) - { - return False; - } - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - q_u->level=level; - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} - /******************************************************************* ********************************************************************/ -- cgit From a041d9061922b1a90e5b5047af77934d908afdd5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 12:09:15 +0100 Subject: s3-spoolss: use is_valid_policy_hnd to check for valid policy handles. Guenther --- source3/rpcclient/cmd_spoolss.c | 40 ++++------------- source3/utils/net_rpc_printer.c | 98 ++++++++++------------------------------- 2 files changed, 31 insertions(+), 107 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index ba01f7aa8b..fe2554e02d 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -469,7 +469,6 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, WERROR result; NTSTATUS status; uint32 info_level = 2; - bool opened_hnd = False; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; const char *printername, *comment = NULL; @@ -500,8 +499,6 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, @@ -529,7 +526,7 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, printf("Success in setting comment.\n"); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -546,7 +543,6 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, WERROR result; NTSTATUS status; uint32 info_level = 2; - bool opened_hnd = False; union spoolss_PrinterInfo info; const char *printername, *new_printername = NULL; @@ -578,8 +574,6 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, @@ -608,7 +602,7 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, printf("Success in setting printername.\n"); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -624,7 +618,6 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR result; uint32 info_level = 1; - bool opened_hnd = False; const char *printername; union spoolss_PrinterInfo info; @@ -649,8 +642,6 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, @@ -685,7 +676,7 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, break; } done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -761,7 +752,6 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; - bool opened_hnd = False; fstring printername; const char *valuename; REGISTRY_VALUE value; @@ -790,8 +780,6 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value); @@ -806,7 +794,7 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -822,7 +810,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR result; NTSTATUS status; - bool opened_hnd = False; fstring printername; const char *valuename, *keyname; REGISTRY_VALUE value; @@ -858,8 +845,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx, @@ -907,7 +892,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, display_reg_value(value); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -1095,7 +1080,6 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR werror; uint32 info_level = 3; - bool opened_hnd = False; const char *printername; uint32 i; bool success = False; @@ -1127,8 +1111,6 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, return werror; } - opened_hnd = True; - /* loop through and print driver info level for each architecture */ for (i=0; archi_table[i].long_archi!=NULL; i++) { @@ -1170,7 +1152,7 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, /* Cleanup */ - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); if ( success ) @@ -1584,7 +1566,6 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, WERROR result; NTSTATUS status; uint32 level = 2; - bool opened_hnd = False; const char *printername; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; @@ -1612,8 +1593,6 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, @@ -1649,7 +1628,7 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, done: /* Cleanup */ - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -2191,7 +2170,6 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, WERROR result; const char *printername; POLICY_HND pol; - bool opened_hnd = False; union spoolss_PrinterInfo info; REGISTRY_VALUE value; TALLOC_CTX *tmp_ctx = talloc_stackframe(); @@ -2240,8 +2218,6 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, @@ -2345,7 +2321,7 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, done: /* cleanup */ TALLOC_FREE(tmp_ctx); - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index f4dd824c84..99012ddf2d 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -1280,7 +1280,6 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ struct spoolss_DevmodeContainer devmode_ctr; struct sec_desc_buf secdesc_ctr; POLICY_HND hnd; - bool got_hnd = false; WERROR result; const char *action_str; @@ -1308,8 +1307,6 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ PRINTER_ALL_ACCESS, pipe_hnd->auth->user_name, &hnd)) goto done; - got_hnd = true; - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; @@ -1357,7 +1354,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ nt_status = NT_STATUS_OK; done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return nt_status; @@ -1432,7 +1429,6 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, PRINTER_INFO_CTR ctr, ctr_pub; union spoolss_PrinterInfo info; POLICY_HND hnd; - bool got_hnd = false; int state; if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr)) @@ -1461,8 +1457,6 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd)) goto done; - got_hnd = true; - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; @@ -1493,7 +1487,7 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, nt_status = NT_STATUS_OK; done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return nt_status; @@ -1533,8 +1527,6 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, uint32 num_printers; uint32 level = 2; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; PRINTER_INFO_CTR ctr_src, ctr_enum; @@ -1600,15 +1592,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; @@ -1633,14 +1621,12 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -1649,11 +1635,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, done: - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); } @@ -1695,8 +1681,6 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, uint32 num_printers; uint32 level = 1; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; PRINTER_INFO_CTR ctr_enum; @@ -1757,17 +1741,11 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; @@ -1829,14 +1807,12 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -1844,10 +1820,10 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -1887,8 +1863,6 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, uint32 num_printers; uint32 level = 3; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; bool got_src_driver_share = false; bool got_dst_driver_share = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; @@ -1972,8 +1946,6 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) goto done; @@ -1986,9 +1958,6 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, &hnd_src)) goto done; - got_hnd_src = true; - - /* in a first step call getdriver for each shared printer (per arch) to get a list of all files that have to be copied */ @@ -2048,15 +2017,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, drivername, printername)); /* close dst */ - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } /* close src */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } } @@ -2064,10 +2031,10 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -2120,8 +2087,6 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, struct cli_state *cli_dst = NULL; POLICY_HND hnd_dst, hnd_src; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct spoolss_SetPrinterInfoCtr info_ctr; @@ -2174,8 +2139,6 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) { DEBUG(1,("could not open printer: %s\n", sharename)); - } else { - got_hnd_dst = true; } /* check for existing dst printer */ @@ -2184,9 +2147,8 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, } else { DEBUG(1,("printer already exists: %s\n", sharename)); /* close printer handle here - dst only, not got src yet. */ - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } continue; } @@ -2199,8 +2161,6 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - /* getprinter on the src server */ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &info_src)) goto done; @@ -2226,24 +2186,22 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, } /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } nt_status = NT_STATUS_OK; done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -2288,8 +2246,6 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, uint32 num_printers, val_needed, data_needed; uint32 level = 2; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; PRINTER_INFO_CTR ctr_enum; @@ -2363,17 +2319,11 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) @@ -2613,14 +2563,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, SAFE_FREE(keylist); /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -2632,10 +2580,10 @@ done: SAFE_FREE(url); SAFE_FREE(unc_name); - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { -- cgit From d1c7bbd893c27ebff28571b4ea611bd3e35148c1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:35:48 +0100 Subject: Convert rpc_sock_read to use tevent_req base async_read --- source3/rpc_client/rpc_transport_sock.c | 57 +++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index c0fa41b0de..68421b3b4c 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -35,6 +35,12 @@ static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state * return 0; } +struct rpc_sock_read_state { + ssize_t received; +}; + +static void rpc_sock_read_done(struct tevent_req *subreq); + static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, uint8_t *data, size_t size, @@ -42,22 +48,53 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - return async_recv(mem_ctx, ev, sock_transp->fd, data, size, 0); + struct async_req *result; + struct tevent_req *subreq; + struct rpc_sock_read_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_sock_read_state)) { + return NULL; + } + + subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = rpc_sock_read_done; + subreq->async.private_data = result; + return result; + fail: + TALLOC_FREE(result); + return NULL; } -static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) +static void rpc_sock_read_done(struct tevent_req *subreq) { - ssize_t received; - int sys_errno; + struct async_req *req = talloc_get_type_abort( + subreq->async.private_data, struct async_req); + struct rpc_sock_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_read_state); + int err; - received = async_syscall_result_ssize_t(req, &sys_errno); - if (received == -1) { - return map_nt_error_from_unix(sys_errno); + state->received = async_recv_recv(subreq, &err); + if (state->received == -1) { + async_req_nterror(req, map_nt_error_from_unix(err)); + return; } - if (received == 0) { - return NT_STATUS_END_OF_FILE; + async_req_done(req); +} + +static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) +{ + struct rpc_sock_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_read_state); + NTSTATUS status; + + if (async_req_is_nterror(req, &status)) { + return status; } - *preceived = received; + *preceived = state->received; return NT_STATUS_OK; } -- cgit From 00ad0c4a4317db810bf2197503006ae5a6bb8bce Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:38:32 +0100 Subject: Remove async_req based async_recv --- lib/async_req/async_sock.c | 68 ---------------------------------------------- lib/async_req/async_sock.h | 3 -- 2 files changed, 71 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 3563421e0e..302265c805 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -310,74 +310,6 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "recv" syscall - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the recv - * @param[in] flags Can only be TEVENT_FD_READ here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_recv_callback(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - struct param_recv *p = &state->param.param_recv; - - if (state->syscall_type != ASYNC_SYSCALL_RECV) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = recv(p->fd, p->buffer, p->length, - p->flags); - state->sys_errno = errno; - - TALLOC_FREE(state->fde); - - async_req_done(req); -} - -/** - * Async version of recv(2) - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to recv from - * @param[in] buffer The buffer to recv into - * @param[in] length How many bytes to recv - * @param[in] flags flags passed to recv(2) - * - * This function is a direct counterpart of recv(2) - */ - -struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_RECV, - fd, TEVENT_FD_READ, async_recv_callback, - &state); - - if (result == NULL) { - return NULL; - } - - state->param.param_recv.fd = fd; - state->param.param_recv.buffer = buffer; - state->param.param_recv.length = length; - state->param.param_recv.flags = flags; - - return result; -} - struct async_send_state { int fd; const void *buf; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index bfc4346d39..1d0558b41e 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -32,9 +32,6 @@ int async_syscall_result_int(struct async_req *req, int *perrno); struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buffer, size_t length, int flags); -struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags); struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, -- cgit From be4913fbe6f6bb2fefbeeb1559692e04a15758f9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:44:26 +0100 Subject: Convert rpc_sock_write to use tevent_req base async_send --- source3/rpc_client/rpc_transport_sock.c | 53 ++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index 68421b3b4c..658ffe30d6 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -98,6 +98,12 @@ static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) return NT_STATUS_OK; } +struct rpc_sock_write_state { + ssize_t sent; +}; + +static void rpc_sock_write_done(struct tevent_req *subreq); + static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, const uint8_t *data, size_t size, @@ -105,19 +111,52 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - return async_send(mem_ctx, ev, sock_transp->fd, data, size, 0); + struct async_req *result; + struct tevent_req *subreq; + struct rpc_sock_write_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_sock_write_state)) { + return NULL; + } + subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = rpc_sock_write_done; + subreq->async.private_data = result; + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_sock_write_done(struct tevent_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.private_data, struct async_req); + struct rpc_sock_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_write_state); + int err; + + state->sent = async_send_recv(subreq, &err); + if (state->sent == -1) { + async_req_nterror(req, map_nt_error_from_unix(err)); + return; + } + async_req_done(req); } static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent) { - ssize_t sent; - int sys_errno; + struct rpc_sock_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_write_state); + NTSTATUS status; - sent = async_syscall_result_ssize_t(req, &sys_errno); - if (sent == -1) { - return map_nt_error_from_unix(sys_errno); + if (async_req_is_nterror(req, &status)) { + return status; } - *psent = sent; + *psent = state->sent; return NT_STATUS_OK; } -- cgit From 423c1d88fcd0f128bceaf8b0c371281aa4a41003 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:45:39 +0100 Subject: Remove async_req based async_send --- lib/async_req/async_sock.c | 232 --------------------------------------------- lib/async_req/async_sock.h | 8 -- 2 files changed, 240 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 302265c805..40e7bca4c8 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -29,45 +29,6 @@ #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) #endif -/** - * Discriminator for async_syscall_state - */ -enum async_syscall_type { - ASYNC_SYSCALL_SEND, - ASYNC_SYSCALL_RECV, -}; - -/** - * Holder for syscall arguments and the result - */ - -struct async_syscall_state { - enum async_syscall_type syscall_type; - struct tevent_fd *fde; - - union { - struct param_send { - int fd; - const void *buffer; - size_t length; - int flags; - } param_send; - struct param_recv { - int fd; - void *buffer; - size_t length; - int flags; - } param_recv; - } param; - - union { - ssize_t result_ssize_t; - size_t result_size_t; - int result_int; - } result; - int sys_errno; -}; - /** * @brief Map async_req states to unix-style errnos * @param[in] req The async req to get the state from @@ -117,199 +78,6 @@ int async_req_simple_recv_errno(struct async_req *req) return 0; } -/** - * @brief Create a new async syscall req - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] type Which syscall will this be - * @param[in] pstate Where to put the newly created private_data state - * @retval The new request - * - * This is a helper function to prepare a new struct async_req with an - * associated struct async_syscall_state. The async_syscall_state will be put - * into the async_req as private_data. - */ - -static struct async_req *async_syscall_new(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - enum async_syscall_type type, - struct async_syscall_state **pstate) -{ - struct async_req *result; - struct async_syscall_state *state; - - if (!async_req_setup(mem_ctx, &result, &state, - struct async_syscall_state)) { - return NULL; - } - state->syscall_type = type; - - result->private_data = state; - - *pstate = state; - - return result; -} - -/** - * @brief Create a new async syscall req based on a fd - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] type Which syscall will this be - * @param[in] fd The file descriptor we work on - * @param[in] fde_flags TEVENT_FD_READ/WRITE -- what are we interested in? - * @param[in] fde_cb The callback function for the file descriptor event - * @param[in] pstate Where to put the newly created private_data state - * @retval The new request - * - * This is a helper function to prepare a new struct async_req with an - * associated struct async_syscall_state and an associated file descriptor - * event. - */ - -static struct async_req *async_fde_syscall_new( - TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - enum async_syscall_type type, - int fd, - uint16_t fde_flags, - void (*fde_cb)(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv), - struct async_syscall_state **pstate) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_syscall_new(mem_ctx, ev, type, &state); - if (result == NULL) { - return NULL; - } - - state->fde = tevent_add_fd(ev, state, fd, fde_flags, fde_cb, result); - if (state->fde == NULL) { - TALLOC_FREE(result); - return NULL; - } - *pstate = state; - return result; -} - -/** - * Retrieve a ssize_t typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - - *perrno = state->sys_errno; - return state->result.result_ssize_t; -} - -/** - * Retrieve a size_t typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -size_t async_syscall_result_size_t(struct async_req *req, int *perrno) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - - *perrno = state->sys_errno; - return state->result.result_size_t; -} - -/** - * Retrieve a int typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -int async_syscall_result_int(struct async_req *req, int *perrno) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - - *perrno = state->sys_errno; - return state->result.result_int; -} - -/** - * fde event handler for the "send" syscall - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the send - * @param[in] flags Can only be TEVENT_FD_WRITE here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_send_callback(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - struct param_send *p = &state->param.param_send; - - if (state->syscall_type != ASYNC_SYSCALL_SEND) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = send(p->fd, p->buffer, p->length, - p->flags); - state->sys_errno = errno; - - TALLOC_FREE(state->fde); - - async_req_done(req); -} - -/** - * Async version of send(2) - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to send to - * @param[in] buffer The buffer to send - * @param[in] length How many bytes to send - * @param[in] flags flags passed to send(2) - * - * This function is a direct counterpart of send(2) - */ - -struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_SEND, - fd, TEVENT_FD_WRITE, async_send_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_send.fd = fd; - state->param.param_send.buffer = buffer; - state->param.param_send.length = length; - state->param.param_send.flags = flags; - - return result; -} - struct async_send_state { int fd; const void *buf; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 1d0558b41e..e001709d27 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -25,14 +25,6 @@ bool async_req_is_errno(struct async_req *req, int *err); int async_req_simple_recv_errno(struct async_req *req); -ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno); -size_t async_syscall_result_size_t(struct async_req *req, int *perrno); -int async_syscall_result_int(struct async_req *req, int *perrno); - -struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags); - struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buf, size_t len, -- cgit From 06b018767b6e6f3ee0221c3aee142cb2b4836fc9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:55:47 +0100 Subject: Fix an incompatible pointer passed to winbind_get_groups This is the same bug that was fixed in other places of the code a few times already: A C compiler ONLY does automatic type conversions during an assignment. Passing down a pointer to type A to a function taking type B as an argument does NOT do any automatic type conversions. If required, I can dig up the relevant portions of the C standard. --- source3/passdb/pdb_wbc_sam.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c index 33dc03fe4c..d2c7fda293 100644 --- a/source3/passdb/pdb_wbc_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -115,10 +115,12 @@ static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods, { size_t i; const char *username = pdb_get_username(user); + uint32_t num_groups; - if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { + if (!winbind_get_groups(mem_ctx, username, &num_groups, pp_gids)) { return NT_STATUS_NO_SUCH_USER; } + *p_num_groups = num_groups; if (*p_num_groups == 0) { smb_panic("primary group missing"); -- cgit From 5bab95b58366ff001b4967bdb0674f42dc990a77 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 13:03:03 +0100 Subject: Fix a missing prototype --- source3/include/proto.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 8084111145..2d92b0fc90 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4693,6 +4693,10 @@ NTSTATUS pdb_nds_init(void); NTSTATUS pdb_smbpasswd_init(void) ; +/* The following definitions come from passdb/pdb_wbc_sam.c */ + +NTSTATUS pdb_wbc_sam_init(void); + /* The following definitions come from passdb/pdb_tdb.c */ bool init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen); -- cgit From 13ac0dc4565b1cbdb977b6959562f3f8f9ac5ff8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 13:53:19 +0100 Subject: tevent: add tevent_req_poll() function metze --- lib/tevent/tevent.h | 3 +++ lib/tevent/tevent_req.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index b3d1c6d59a..b3611228aa 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -296,6 +296,9 @@ struct tevent_req *tevent_req_post(struct tevent_req *req, bool tevent_req_is_in_progress(struct tevent_req *req); +bool tevent_req_poll(struct tevent_req *req, + struct tevent_context *ev); + bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, uint64_t *error); diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 800e3855d1..c17587b16c 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -235,6 +235,21 @@ bool tevent_req_is_in_progress(struct tevent_req *req) return false; } +bool tevent_req_poll(struct tevent_req *req, + struct tevent_context *ev) +{ + while (tevent_req_is_in_progress(req)) { + int ret; + + ret = tevent_loop_once(ev); + if (ret != 0) { + return false; + } + } + + return true; +} + bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, uint64_t *error) { -- cgit From 2390ea274bff7a8878a488db0893a393c9d1b51e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 13:19:12 +0100 Subject: s3-rpcclient: more uses of is_valid_policy_hnd in spoolss and samr commands. Guenther --- source3/rpcclient/cmd_samr.c | 32 +++++++------------------------- source3/rpcclient/cmd_spoolss.c | 25 +++++-------------------- 2 files changed, 12 insertions(+), 45 deletions(-) diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 31977e9554..936c2081f3 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -789,7 +789,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, struct samr_SamArray *dom_users = NULL; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; uint32 acb_mask = ACB_NORMAL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 1) || (argc > 3)) { printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]); @@ -811,8 +810,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = rpccli_samr_OpenDomain(cli, mem_ctx, @@ -824,8 +821,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate domain users */ start_idx = 0; @@ -852,10 +847,10 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -872,7 +867,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, uint32 start_idx, size, num_dom_groups, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; struct samr_SamArray *dom_groups = NULL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 1) || (argc > 2)) { printf("Usage: %s [access_mask]\n", argv[0]); @@ -891,8 +885,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = rpccli_samr_OpenDomain(cli, mem_ctx, @@ -904,8 +896,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate domain groups */ start_idx = 0; @@ -930,10 +920,10 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -950,7 +940,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, uint32 start_idx, size, num_als_groups, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; struct samr_SamArray *als_groups = NULL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 2) || (argc > 3)) { printf("Usage: %s builtin|domain [access mask]\n", argv[0]); @@ -969,8 +958,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = get_domain_handle(cli, mem_ctx, argv[1], @@ -982,8 +969,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate alias groups */ start_idx = 0; @@ -1008,10 +993,10 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -1027,7 +1012,6 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx, size, num_entries, i; uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - bool got_connect_pol = false; struct samr_SamArray *sam = NULL; if ((argc < 1) || (argc > 2)) { @@ -1049,8 +1033,6 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, goto done; } - got_connect_pol = true; - /* Enumerate alias groups */ start_idx = 0; @@ -1075,7 +1057,7 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_connect_pol) { + if (is_valid_policy_hnd(&connect_pol)) { rpccli_samr_Close(cli, mem_ctx, &connect_pol); } diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index fe2554e02d..eaee516ad5 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1812,7 +1812,6 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; union spoolss_AddFormInfo info; struct spoolss_AddFormInfo1 info1; @@ -1834,8 +1833,6 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Dummy up some values for the form data */ info1.flags = FORM_USER; @@ -1859,7 +1856,7 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c &werror); done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -1875,7 +1872,6 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; union spoolss_AddFormInfo info; struct spoolss_AddFormInfo1 info1; @@ -1897,8 +1893,6 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Dummy up some values for the form data */ info1.flags = FORM_PRINTER; @@ -1922,7 +1916,7 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c &werror); done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -1991,7 +1985,6 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; DATA_BLOB buffer; uint32_t offered = 0; union spoolss_FormInfo info; @@ -2015,8 +2008,6 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Get the form */ status = rpccli_spoolss_GetForm(cli, mem_ctx, @@ -2048,7 +2039,7 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c display_form_info1(&info.info1); done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -2065,7 +2056,6 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; /* Parse the command arguments */ @@ -2085,8 +2075,6 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Delete the form */ status = rpccli_spoolss_DeleteForm(cli, mem_ctx, @@ -2098,7 +2086,7 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, } done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -2114,7 +2102,6 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, POLICY_HND handle; WERROR werror; const char *printername; - bool got_handle = False; uint32 num_forms, level = 1, i; FORM_1 *forms; @@ -2136,8 +2123,6 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Enumerate forms */ werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms); @@ -2154,7 +2139,7 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, } done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; -- cgit From c46fad3d1bdf1082a695d3df90e55e739e494a5c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 13:45:15 +0100 Subject: spoolss: add spoolss_FormInfo2 used by Vista. Guenther --- librpc/idl/spoolss.idl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 3e35399f8d..5359fdf4a2 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1237,8 +1237,28 @@ import "misc.idl", "security.idl", "winreg.idl"; spoolss_FormArea area; } spoolss_FormInfo1; + typedef [bitmap32bit] bitmap { + SPOOLSS_FORM_STRING_TYPE_NONE = 0x00000001, + SPOOLSS_FORM_STRING_TYPE_MUI_DLL = 0x00000002, + SPOOLSS_FORM_STRING_TYPE_LANG_PAIR = 0x00000004 + } spoolss_FormStringType; + + typedef struct { + spoolss_FormFlags flags; + [relative] nstring *form_name; + spoolss_FormSize size; + spoolss_FormArea area; + [relative] nstring *keyword; + spoolss_FormStringType string_type; + [relative] nstring *mui_dll; + uint32 ressource_id; + [relative] nstring *display_name; + uint32 lang_id; + } spoolss_FormInfo2; + typedef [nodiscriminant,relative_base,public,gensize] union { [case(1)] spoolss_FormInfo1 info1; + [case(2)] spoolss_FormInfo2 info2; [default]; } spoolss_FormInfo; -- cgit From 80a9a41d412aa61877a7497661197fd16ddb4903 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 14:20:40 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 293 +++++++++++++++++++++++++++++++++++++++++++ librpc/gen_ndr/ndr_spoolss.h | 2 + librpc/gen_ndr/spoolss.h | 19 +++ 3 files changed, 314 insertions(+) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index fdafa2582b..25c9dc49d7 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -12232,6 +12232,275 @@ _PUBLIC_ void ndr_print_spoolss_FormInfo1(struct ndr_print *ndr, const char *nam ndr->depth--; } +static enum ndr_err_code ndr_push_spoolss_FormStringType(struct ndr_push *ndr, int ndr_flags, uint32_t r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_FormStringType(struct ndr_pull *ndr, int ndr_flags, uint32_t *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_FormStringType(struct ndr_print *ndr, const char *name, uint32_t r) +{ + ndr_print_uint32(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SPOOLSS_FORM_STRING_TYPE_NONE", SPOOLSS_FORM_STRING_TYPE_NONE, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SPOOLSS_FORM_STRING_TYPE_MUI_DLL", SPOOLSS_FORM_STRING_TYPE_MUI_DLL, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SPOOLSS_FORM_STRING_TYPE_LANG_PAIR", SPOOLSS_FORM_STRING_TYPE_LANG_PAIR, r); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_spoolss_FormInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_FormInfo2 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_spoolss_FormFlags(ndr, NDR_SCALARS, r->flags)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->form_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_spoolss_FormSize(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_push_spoolss_FormArea(ndr, NDR_SCALARS, &r->area)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->keyword)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_spoolss_FormStringType(ndr, NDR_SCALARS, r->string_type)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->mui_dll)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ressource_id)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->display_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->lang_id)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->form_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->form_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->form_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->keyword) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->keyword)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->keyword)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->mui_dll) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->mui_dll)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->mui_dll)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->display_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->display_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->display_name)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_FormInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_FormInfo2 *r) +{ + uint32_t _ptr_form_name; + TALLOC_CTX *_mem_save_form_name_0; + uint32_t _ptr_keyword; + TALLOC_CTX *_mem_save_keyword_0; + uint32_t _ptr_mui_dll; + TALLOC_CTX *_mem_save_mui_dll_0; + uint32_t _ptr_display_name; + TALLOC_CTX *_mem_save_display_name_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_spoolss_FormFlags(ndr, NDR_SCALARS, &r->flags)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_form_name)); + if (_ptr_form_name) { + NDR_PULL_ALLOC(ndr, r->form_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->form_name, _ptr_form_name)); + } else { + r->form_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_spoolss_FormSize(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_spoolss_FormArea(ndr, NDR_SCALARS, &r->area)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_keyword)); + if (_ptr_keyword) { + NDR_PULL_ALLOC(ndr, r->keyword); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->keyword, _ptr_keyword)); + } else { + r->keyword = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_spoolss_FormStringType(ndr, NDR_SCALARS, &r->string_type)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_mui_dll)); + if (_ptr_mui_dll) { + NDR_PULL_ALLOC(ndr, r->mui_dll); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->mui_dll, _ptr_mui_dll)); + } else { + r->mui_dll = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ressource_id)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_display_name)); + if (_ptr_display_name) { + NDR_PULL_ALLOC(ndr, r->display_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->display_name, _ptr_display_name)); + } else { + r->display_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->lang_id)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->form_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->form_name)); + _mem_save_form_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->form_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->form_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_form_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->keyword) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->keyword)); + _mem_save_keyword_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->keyword, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->keyword)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_keyword_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->mui_dll) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->mui_dll)); + _mem_save_mui_dll_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->mui_dll, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->mui_dll)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_mui_dll_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->display_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->display_name)); + _mem_save_display_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->display_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->display_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_display_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_FormInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_FormInfo2 *r) +{ + ndr_print_struct(ndr, name, "spoolss_FormInfo2"); + ndr->depth++; + ndr_print_spoolss_FormFlags(ndr, "flags", r->flags); + ndr_print_ptr(ndr, "form_name", r->form_name); + ndr->depth++; + if (r->form_name) { + ndr_print_string(ndr, "form_name", r->form_name); + } + ndr->depth--; + ndr_print_spoolss_FormSize(ndr, "size", &r->size); + ndr_print_spoolss_FormArea(ndr, "area", &r->area); + ndr_print_ptr(ndr, "keyword", r->keyword); + ndr->depth++; + if (r->keyword) { + ndr_print_string(ndr, "keyword", r->keyword); + } + ndr->depth--; + ndr_print_spoolss_FormStringType(ndr, "string_type", r->string_type); + ndr_print_ptr(ndr, "mui_dll", r->mui_dll); + ndr->depth++; + if (r->mui_dll) { + ndr_print_string(ndr, "mui_dll", r->mui_dll); + } + ndr->depth--; + ndr_print_uint32(ndr, "ressource_id", r->ressource_id); + ndr_print_ptr(ndr, "display_name", r->display_name); + ndr->depth++; + if (r->display_name) { + ndr_print_string(ndr, "display_name", r->display_name); + } + ndr->depth--; + ndr_print_uint32(ndr, "lang_id", r->lang_id); + ndr->depth--; +} + _PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_FormInfo *r) { uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr); @@ -12244,6 +12513,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int n NDR_CHECK(ndr_push_spoolss_FormInfo1(ndr, NDR_SCALARS, &r->info1)); break; } + case 2: { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_FormInfo2(ndr, NDR_SCALARS, &r->info2)); + break; } + default: { break; } @@ -12257,6 +12532,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int n NDR_CHECK(ndr_push_spoolss_FormInfo1(ndr, NDR_BUFFERS, &r->info1)); break; + case 2: + NDR_CHECK(ndr_push_spoolss_FormInfo2(ndr, NDR_BUFFERS, &r->info2)); + break; + default: break; @@ -12279,6 +12558,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_FormInfo(struct ndr_pull *ndr, int n NDR_CHECK(ndr_pull_spoolss_FormInfo1(ndr, NDR_SCALARS, &r->info1)); break; } + case 2: { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_FormInfo2(ndr, NDR_SCALARS, &r->info2)); + break; } + default: { break; } @@ -12291,6 +12576,10 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_FormInfo(struct ndr_pull *ndr, int n NDR_CHECK(ndr_pull_spoolss_FormInfo1(ndr, NDR_BUFFERS, &r->info1)); break; + case 2: + NDR_CHECK(ndr_pull_spoolss_FormInfo2(ndr, NDR_BUFFERS, &r->info2)); + break; + default: break; @@ -12310,6 +12599,10 @@ _PUBLIC_ void ndr_print_spoolss_FormInfo(struct ndr_print *ndr, const char *name ndr_print_spoolss_FormInfo1(ndr, "info1", &r->info1); break; + case 2: + ndr_print_spoolss_FormInfo2(ndr, "info2", &r->info2); + break; + default: break; diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index 5b32d510c0..5ecadc04d6 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -344,6 +344,8 @@ void ndr_print_spoolss_FormFlags(struct ndr_print *ndr, const char *name, enum s void ndr_print_spoolss_FormSize(struct ndr_print *ndr, const char *name, const struct spoolss_FormSize *r); void ndr_print_spoolss_FormArea(struct ndr_print *ndr, const char *name, const struct spoolss_FormArea *r); void ndr_print_spoolss_FormInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_FormInfo1 *r); +void ndr_print_spoolss_FormStringType(struct ndr_print *ndr, const char *name, uint32_t r); +void ndr_print_spoolss_FormInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_FormInfo2 *r); enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_FormInfo *r); enum ndr_err_code ndr_pull_spoolss_FormInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_FormInfo *r); void ndr_print_spoolss_FormInfo(struct ndr_print *ndr, const char *name, const union spoolss_FormInfo *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index ad4554dbe5..ff2eb1b8c0 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -958,8 +958,27 @@ struct spoolss_FormInfo1 { struct spoolss_FormArea area; }; +/* bitmap spoolss_FormStringType */ +#define SPOOLSS_FORM_STRING_TYPE_NONE ( 0x00000001 ) +#define SPOOLSS_FORM_STRING_TYPE_MUI_DLL ( 0x00000002 ) +#define SPOOLSS_FORM_STRING_TYPE_LANG_PAIR ( 0x00000004 ) + +struct spoolss_FormInfo2 { + enum spoolss_FormFlags flags; + const char * form_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + struct spoolss_FormSize size; + struct spoolss_FormArea area; + const char * keyword;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + uint32_t string_type; + const char * mui_dll;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + uint32_t ressource_id; + const char * display_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + uint32_t lang_id; +}; + union spoolss_FormInfo { struct spoolss_FormInfo1 info1;/* [case] */ + struct spoolss_FormInfo2 info2;/* [case(2)] */ }/* [relative_base,gensize,public,nodiscriminant] */; struct spoolss_AddFormInfo1 { -- cgit From 01d1aaf63e8170936139a01814211f6567c4b125 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 13:46:08 +0100 Subject: s3-rpcclient: allow to set level in spoolss getform query and display all levels. Guenther --- source3/rpcclient/cmd_spoolss.c | 47 +++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index eaee516ad5..51fcaaa54c 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1978,6 +1978,28 @@ static void display_form_info1(struct spoolss_FormInfo1 *r) /**************************************************************************** ****************************************************************************/ +static void display_form_info2(struct spoolss_FormInfo2 *r) +{ + printf("%s\n" \ + "\tflag: %s (%d)\n" \ + "\twidth: %d, length: %d\n" \ + "\tleft: %d, right: %d, top: %d, bottom: %d\n", + r->form_name, get_form_flag(r->flags), r->flags, + r->size.width, r->size.height, + r->area.left, r->area.right, + r->area.top, r->area.bottom); + printf("\tkeyword: %s\n", r->keyword); + printf("\tstring_type: 0x%08x\n", r->string_type); + printf("\tmui_dll: %s\n", r->mui_dll); + printf("\tressource_id: 0x%08x\n", r->ressource_id); + printf("\tdisplay_name: %s\n", r->display_name); + printf("\tlang_id: %d\n", r->lang_id); + printf("\n"); +} + +/**************************************************************************** +****************************************************************************/ + static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { @@ -1989,11 +2011,12 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c uint32_t offered = 0; union spoolss_FormInfo info; uint32_t needed; + uint32_t level = 1; /* Parse the command arguments */ - if (argc != 3) { - printf ("Usage: %s \n", argv[0]); + if (argc < 3 || argc > 5) { + printf ("Usage: %s [level]\n", argv[0]); return WERR_OK; } @@ -2008,24 +2031,28 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; + if (argc == 4) { + level = atoi(argv[3]); + } + /* Get the form */ status = rpccli_spoolss_GetForm(cli, mem_ctx, &handle, argv[2], - 1, + level, NULL, offered, &info, &needed, &werror); if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { - buffer = data_blob_talloc(mem_ctx, NULL, needed); + buffer = data_blob_talloc_zero(mem_ctx, needed); offered = needed; status = rpccli_spoolss_GetForm(cli, mem_ctx, &handle, argv[2], - 1, + level, &buffer, offered, &info, @@ -2037,7 +2064,15 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c return werror; } - display_form_info1(&info.info1); + switch (level) { + case 1: + display_form_info1(&info.info1); + break; + case 2: + display_form_info2(&info.info2); + break; + } + done: if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); -- cgit From e2f37ec106fb51ec894e0d6160949545e80dfe69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 14:29:31 +0100 Subject: tevent: add private_print function feature to tevent_req metze --- lib/tevent/tevent.h | 11 +++++++++++ lib/tevent/tevent_req.c | 27 ++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index b3611228aa..185a8fa193 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -211,6 +211,15 @@ struct tevent_req { */ void *private_state; + /** + * @brief A function to overwrite the default print function + * + * The implementation doing the work may want to imeplement a + * custom function to print the text representation of the async + * request. + */ + char *(*private_print)(struct tevent_req *req, TALLOC_CTX *mem_ctx); + /** * @brief Internal state of the request * @@ -267,6 +276,8 @@ struct tevent_req { } internal; }; +char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); + char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index c17587b16c..e243c7de5d 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -28,14 +28,17 @@ #include "tevent_util.h" /** - * @brief Print an tevent_req structure in debug messages - * @param[in] mem_ctx The memory context for the result + * @brief The default print function for creating debug messages * @param[in] req The request to be printed + * @param[in] mem_ctx The memory context for the result * @retval Text representation of req * + * The function should not be used by users of the asynx API, + * but custom print function can use it and append custom text + * to the string. */ -char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) +char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) { return talloc_asprintf(mem_ctx, "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] " @@ -50,6 +53,24 @@ char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) ); } +/** + * @brief Print an tevent_req structure in debug messages + * @param[in] mem_ctx The memory context for the result + * @param[in] req The request to be printed + * @retval Text representation of req + * + * This function should be used by callers of the async API + */ + +char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) +{ + if (!req->private_print) { + return tevent_req_default_print(req, mem_ctx); + } + + return req->private_print(req, mem_ctx); +} + /** * @brief Create an async request * @param[in] mem_ctx The memory context for the result -- cgit From fc3ffedcfe173900d65f6fa7db3a3cf2608f9f68 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 25 Feb 2009 15:05:43 +0100 Subject: Don't define _GNU_SOURCE if it's already defined on the command-line. --- pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index af6885f67a..0e4a7e2289 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -2548,7 +2548,9 @@ sub GenerateIncludes($) if (is_intree()) { $self->pidl("#include \"includes.h\""); } else { + $self->pidl("#ifndef _GNU_SOURCE"); $self->pidl("#define _GNU_SOURCE"); + $self->pidl("#endif"); $self->pidl("#include "); $self->pidl("#include "); $self->pidl("#include "); -- cgit From 543db0f94aa4cdeb6499f62aee8791cda7a670d7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 15:04:55 +0100 Subject: s3:events: map TEVENT_DEBUG_TRACE to debug level 10 metze --- source3/lib/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/events.c b/source3/lib/events.c index 44b4562757..9e81a47796 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -282,7 +282,7 @@ static void s3_event_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 5; + samba_level = 10; break; }; -- cgit From 2bd8cacf0e5ed6965f5791c4a86320d4978d9b15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 15:05:24 +0100 Subject: s4:lib/events: map TEVENT_DEBUG_TRACE to debug level 10 metze --- source4/lib/events/tevent_s4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/lib/events/tevent_s4.c b/source4/lib/events/tevent_s4.c index a05ac0796f..89ca7bbe5c 100644 --- a/source4/lib/events/tevent_s4.c +++ b/source4/lib/events/tevent_s4.c @@ -41,7 +41,7 @@ static void ev_wrap_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 5; + samba_level = 10; break; }; -- cgit From b6457c78d61992f12903ed0966d9d1608de68da8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 14:27:30 +0100 Subject: s3-spoolss: remove unused decode_printer_info_7. Guenther --- source3/rpc_client/cli_spoolss.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index c9d23efdf2..4c1d57e063 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -359,38 +359,6 @@ static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, return True; } -/********************************************************************** -**********************************************************************/ - -static bool decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_7 **info) -{ - uint32 i; - PRINTER_INFO_7 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PRINTER_INFO_7)); - } else { - inf = NULL; - } - - prs_set_offset(&buffer->prs,0); - - for (i=0; i Date: Wed, 25 Feb 2009 15:21:36 +0100 Subject: Include header with NTSTATUS, as some IDL files use it. --- pidl/lib/Parse/Pidl/Samba4/Header.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pidl/lib/Parse/Pidl/Samba4/Header.pm b/pidl/lib/Parse/Pidl/Samba4/Header.pm index 0411466c82..5315957946 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -407,6 +407,9 @@ sub Parse($) } pidl "#include \n"; pidl "\n"; + # FIXME: Include this only if NTSTATUS was actually used + pidl choose_header("libcli/util/ntstatus.h", "core/ntstatus.h") . "\n"; + pidl "\n"; foreach (@{$ndr}) { ($_->{TYPE} eq "CPP_QUOTE") && HeaderQuote($_); -- cgit From 838b950138255beb7135a32d4429a74fec2bfe42 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 25 Feb 2009 15:22:08 +0100 Subject: Rerun pidl. --- librpc/gen_ndr/dfs.h | 2 ++ librpc/gen_ndr/drsblobs.h | 2 ++ librpc/gen_ndr/drsuapi.h | 2 ++ librpc/gen_ndr/dssetup.h | 2 ++ librpc/gen_ndr/echo.h | 2 ++ librpc/gen_ndr/epmapper.h | 2 ++ librpc/gen_ndr/eventlog.h | 2 ++ librpc/gen_ndr/initshutdown.h | 2 ++ librpc/gen_ndr/krb5pac.h | 2 ++ librpc/gen_ndr/lsa.h | 2 ++ librpc/gen_ndr/misc.h | 2 ++ librpc/gen_ndr/named_pipe_auth.h | 2 ++ librpc/gen_ndr/nbt.h | 2 ++ librpc/gen_ndr/netlogon.h | 2 ++ librpc/gen_ndr/ntsvcs.h | 2 ++ librpc/gen_ndr/samr.h | 2 ++ librpc/gen_ndr/security.h | 2 ++ librpc/gen_ndr/spoolss.h | 2 ++ librpc/gen_ndr/srvsvc.h | 2 ++ librpc/gen_ndr/svcctl.h | 2 ++ librpc/gen_ndr/winreg.h | 2 ++ librpc/gen_ndr/wkssvc.h | 2 ++ librpc/gen_ndr/xattr.h | 2 ++ 23 files changed, 46 insertions(+) diff --git a/librpc/gen_ndr/dfs.h b/librpc/gen_ndr/dfs.h index 07548c3742..41be3bd28d 100644 --- a/librpc/gen_ndr/dfs.h +++ b/librpc/gen_ndr/dfs.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #ifndef _HEADER_netdfs #define _HEADER_netdfs diff --git a/librpc/gen_ndr/drsblobs.h b/librpc/gen_ndr/drsblobs.h index bb33464c76..190e012cb5 100644 --- a/librpc/gen_ndr/drsblobs.h +++ b/librpc/gen_ndr/drsblobs.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/drsuapi.h" #include "librpc/gen_ndr/misc.h" #include "librpc/gen_ndr/samr.h" diff --git a/librpc/gen_ndr/drsuapi.h b/librpc/gen_ndr/drsuapi.h index e3d480365e..8f9b165631 100644 --- a/librpc/gen_ndr/drsuapi.h +++ b/librpc/gen_ndr/drsuapi.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/misc.h" #include "librpc/gen_ndr/samr.h" diff --git a/librpc/gen_ndr/dssetup.h b/librpc/gen_ndr/dssetup.h index d284a63375..5d254fe92e 100644 --- a/librpc/gen_ndr/dssetup.h +++ b/librpc/gen_ndr/dssetup.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #ifndef _HEADER_dssetup #define _HEADER_dssetup diff --git a/librpc/gen_ndr/echo.h b/librpc/gen_ndr/echo.h index 79d4220714..9c783046f3 100644 --- a/librpc/gen_ndr/echo.h +++ b/librpc/gen_ndr/echo.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #ifndef _HEADER_rpcecho #define _HEADER_rpcecho diff --git a/librpc/gen_ndr/epmapper.h b/librpc/gen_ndr/epmapper.h index e5155a8cad..ff80fbb4fd 100644 --- a/librpc/gen_ndr/epmapper.h +++ b/librpc/gen_ndr/epmapper.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #ifndef _HEADER_epmapper #define _HEADER_epmapper diff --git a/librpc/gen_ndr/eventlog.h b/librpc/gen_ndr/eventlog.h index 2a9b824601..b6e792fdd3 100644 --- a/librpc/gen_ndr/eventlog.h +++ b/librpc/gen_ndr/eventlog.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/lsa.h" #include "librpc/gen_ndr/security.h" #ifndef _HEADER_eventlog diff --git a/librpc/gen_ndr/initshutdown.h b/librpc/gen_ndr/initshutdown.h index 014e2fe689..913eb8f740 100644 --- a/librpc/gen_ndr/initshutdown.h +++ b/librpc/gen_ndr/initshutdown.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/lsa.h" #ifndef _HEADER_initshutdown #define _HEADER_initshutdown diff --git a/librpc/gen_ndr/krb5pac.h b/librpc/gen_ndr/krb5pac.h index 73bd0d95bb..03b23bdaae 100644 --- a/librpc/gen_ndr/krb5pac.h +++ b/librpc/gen_ndr/krb5pac.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/netlogon.h" #include "librpc/gen_ndr/samr.h" diff --git a/librpc/gen_ndr/lsa.h b/librpc/gen_ndr/lsa.h index 03a0464d5b..a6da7a6cef 100644 --- a/librpc/gen_ndr/lsa.h +++ b/librpc/gen_ndr/lsa.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #include "librpc/gen_ndr/security.h" #ifndef _HEADER_lsarpc diff --git a/librpc/gen_ndr/misc.h b/librpc/gen_ndr/misc.h index e000cb0624..824483d292 100644 --- a/librpc/gen_ndr/misc.h +++ b/librpc/gen_ndr/misc.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #ifndef _HEADER_misc #define _HEADER_misc diff --git a/librpc/gen_ndr/named_pipe_auth.h b/librpc/gen_ndr/named_pipe_auth.h index 7ca7444c92..e35c221118 100644 --- a/librpc/gen_ndr/named_pipe_auth.h +++ b/librpc/gen_ndr/named_pipe_auth.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/netlogon.h" #ifndef _HEADER_named_pipe_auth #define _HEADER_named_pipe_auth diff --git a/librpc/gen_ndr/nbt.h b/librpc/gen_ndr/nbt.h index 1f3ad37d9b..affbeffa08 100644 --- a/librpc/gen_ndr/nbt.h +++ b/librpc/gen_ndr/nbt.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/svcctl.h" diff --git a/librpc/gen_ndr/netlogon.h b/librpc/gen_ndr/netlogon.h index d1038d76c8..892e770bad 100644 --- a/librpc/gen_ndr/netlogon.h +++ b/librpc/gen_ndr/netlogon.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #include "librpc/gen_ndr/lsa.h" #include "librpc/gen_ndr/samr.h" diff --git a/librpc/gen_ndr/ntsvcs.h b/librpc/gen_ndr/ntsvcs.h index 5021aa2252..804c452816 100644 --- a/librpc/gen_ndr/ntsvcs.h +++ b/librpc/gen_ndr/ntsvcs.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/winreg.h" #ifndef _HEADER_ntsvcs #define _HEADER_ntsvcs diff --git a/librpc/gen_ndr/samr.h b/librpc/gen_ndr/samr.h index 782987de1c..044756469e 100644 --- a/librpc/gen_ndr/samr.h +++ b/librpc/gen_ndr/samr.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #include "librpc/gen_ndr/lsa.h" #include "librpc/gen_ndr/security.h" diff --git a/librpc/gen_ndr/security.h b/librpc/gen_ndr/security.h index 4fa9a8084c..32ea2eaacd 100644 --- a/librpc/gen_ndr/security.h +++ b/librpc/gen_ndr/security.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #define dom_sid2 dom_sid #define dom_sid28 dom_sid diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index ad4554dbe5..c960d5439b 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/winreg.h" diff --git a/librpc/gen_ndr/srvsvc.h b/librpc/gen_ndr/srvsvc.h index 6467f72a5b..4a8fd051f6 100644 --- a/librpc/gen_ndr/srvsvc.h +++ b/librpc/gen_ndr/srvsvc.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/svcctl.h" #ifndef _HEADER_srvsvc diff --git a/librpc/gen_ndr/svcctl.h b/librpc/gen_ndr/svcctl.h index 328d8ab517..6ba0e4f378 100644 --- a/librpc/gen_ndr/svcctl.h +++ b/librpc/gen_ndr/svcctl.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/misc.h" #include "librpc/gen_ndr/security.h" #ifndef _HEADER_svcctl diff --git a/librpc/gen_ndr/winreg.h b/librpc/gen_ndr/winreg.h index 79cf33e769..e0300fd0e7 100644 --- a/librpc/gen_ndr/winreg.h +++ b/librpc/gen_ndr/winreg.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/lsa.h" #include "librpc/gen_ndr/security.h" #ifndef _HEADER_winreg diff --git a/librpc/gen_ndr/wkssvc.h b/librpc/gen_ndr/wkssvc.h index dc12fe2a3f..19aa126322 100644 --- a/librpc/gen_ndr/wkssvc.h +++ b/librpc/gen_ndr/wkssvc.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/srvsvc.h" #include "librpc/gen_ndr/lsa.h" #ifndef _HEADER_wkssvc diff --git a/librpc/gen_ndr/xattr.h b/librpc/gen_ndr/xattr.h index 1148a0acec..1ce58f7ec6 100644 --- a/librpc/gen_ndr/xattr.h +++ b/librpc/gen_ndr/xattr.h @@ -2,6 +2,8 @@ #include +#include "libcli/util/ntstatus.h" + #include "librpc/gen_ndr/security.h" #ifndef _HEADER_xattr #define _HEADER_xattr -- cgit From fd3f3e68f2e6be0196473f641f8edb41e40ca761 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 25 Feb 2009 10:02:41 -0500 Subject: Use stdbool.h instead of manually defining bool --- source4/lib/ldb/include/ldb.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index eb8e0ed11e..be41151409 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -46,16 +46,7 @@ #define _LDB_H_ 1 /*! \endcond */ -#ifndef bool -typedef int bool; -#endif -#ifndef true -#define true 1 -#endif -#ifndef false -#define false 0 -#endif - +#include #include "talloc.h" #include "tevent.h" #include "ldb_errors.h" -- cgit From d7c7b31bbaf110446ea835b66845ab6f0ee09231 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 25 Feb 2009 16:54:35 +0100 Subject: Only define _GNU_SOURCE if it's not defined yet. --- pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm index f8209be654..f2a96a3037 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm @@ -131,7 +131,9 @@ sub Parse($$$$) if (is_intree()) { $res .= "#include \"includes.h\"\n"; } else { + $res .= "#ifndef _GNU_SOURCE\n"; $res .= "#define _GNU_SOURCE\n"; + $res .= "#endif\n"; $res .= "#include \n"; $res .= "#include \n"; $res .= "#include \n"; -- cgit From 15f108f0917eedab89199e9fbf93ed802eed7f89 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2009 09:59:53 -0800 Subject: Fix some NetBSD warnings. Jeremy. --- source3/printing/nt_printing.c | 6 ++++-- source3/smbd/reply.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index bbe8ebc2bc..b254ce0b95 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1381,7 +1381,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr goto error_exit; } old_create_time = st.st_mtime; - DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time)); + DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", + (long)old_create_time)); } } close_file(NULL, fsp, NORMAL_CLOSE); @@ -1432,7 +1433,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr goto error_exit; } new_create_time = st.st_mtime; - DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time)); + DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", + (long)new_create_time)); } } close_file(NULL, fsp, NORMAL_CLOSE); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index b30ef23c0e..80ed019e0f 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2808,9 +2808,9 @@ static void send_file_readbraw(connection_struct *conn, } return; } -#endif normal_readbraw: +#endif outbuf = TALLOC_ARRAY(NULL, char, nread+4); if (!outbuf) { -- cgit From f90250b54923588d756a02e76876fc66a6c68074 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Wed, 25 Feb 2009 11:27:37 -0800 Subject: s4: make libintl a build dependency of heimdal_krb5 so all dependent binaries are linked properly --- source4/heimdal_build/internal.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/heimdal_build/internal.mk b/source4/heimdal_build/internal.mk index 9e32898a07..77dbf0fb98 100644 --- a/source4/heimdal_build/internal.mk +++ b/source4/heimdal_build/internal.mk @@ -255,7 +255,7 @@ HEIMDAL_GSSAPI_OBJ_FILES = \ CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/krb5 -I$(heimdalsrcdir)/lib/asn1 -I$(heimdalsrcdir)/lib/com_err PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_PKINIT_ASN1 HEIMDAL_WIND \ HEIMDAL_KRB5_ASN1 HEIMDAL_HX509 HEIMDAL_HCRYPTO \ - LIBNETIF LIBSAMBA-HOSTCONFIG + LIBNETIF LIBSAMBA-HOSTCONFIG INTL PUBLIC_DEPENDENCIES = HEIMDAL_COM_ERR # End SUBSYSTEM HEIMDAL_KRB5 ####################### -- cgit From 74232e323762abc8fbdc2a6a28c6e77b0020c304 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 16:17:08 +0100 Subject: spoolss: windows ignores level in a spoolss_GetPrintProcessorDirectory query. Guenther --- librpc/idl/spoolss.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 5359fdf4a2..23dc519654 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1021,7 +1021,7 @@ import "misc.idl", "security.idl", "winreg.idl"; typedef [nodiscriminant,relative_base,gensize,public] union { [case(1)] spoolss_PrintProcessorDirectoryInfo1 info1; - [default]; + [default] spoolss_PrintProcessorDirectoryInfo1 info1; } spoolss_PrintProcessorDirectoryInfo; WERROR spoolss_GetPrintProcessorDirectory( -- cgit From 92f05e3c96a412d50cf8733d393464acb1d702fd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 20:46:35 +0100 Subject: spoolss: fix spoolss_FormInfo2 (new in vista). keyword is an astring, not an nstring. Guenther --- librpc/idl/spoolss.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 23dc519654..b1ece7360f 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1248,7 +1248,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *form_name; spoolss_FormSize size; spoolss_FormArea area; - [relative] nstring *keyword; + [relative] astring *keyword; spoolss_FormStringType string_type; [relative] nstring *mui_dll; uint32 ressource_id; -- cgit From b239a4ee76ec424f09a74ae65bbddeba71026141 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 20:48:16 +0100 Subject: spoolss: add spoolss_AddFormInfo2. Guenther --- librpc/idl/spoolss.idl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index b1ece7360f..1271ca407b 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1269,8 +1269,22 @@ import "misc.idl", "security.idl", "winreg.idl"; spoolss_FormArea area; } spoolss_AddFormInfo1; + typedef struct { + spoolss_FormFlags flags; + [string,charset(UTF16)] uint16 *form_name; + spoolss_FormSize size; + spoolss_FormArea area; + [string,charset(DOS)] uint8 *keyword; + spoolss_FormStringType string_type; + [string,charset(UTF16)] uint16 *mui_dll; + uint32 ressource_id; + [string,charset(UTF16)] uint16 *display_name; + uint32 lang_id; + } spoolss_AddFormInfo2; + typedef [switch_type(uint32)] union { [case(1)] spoolss_AddFormInfo1 *info1; + [case(2)] spoolss_AddFormInfo2 *info2; } spoolss_AddFormInfo; WERROR spoolss_AddForm( -- cgit From 06d2604d9d1f77dddc1408233da48f0958bb24d0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 20:48:43 +0100 Subject: spoolss: add JOB_ACCESS_READ. Guenther --- librpc/idl/spoolss.idl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 1271ca407b..2aebed5016 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1841,7 +1841,8 @@ import "misc.idl", "security.idl", "winreg.idl"; SERVER_ACCESS_ENUMERATE = 0x00000002, PRINTER_ACCESS_ADMINISTER = 0x00000004, PRINTER_ACCESS_USE = 0x00000008, - JOB_ACCESS_ADMINISTER = 0x00000010 + JOB_ACCESS_ADMINISTER = 0x00000010, + JOB_ACCESS_READ = 0x00000020 } spoolss_AccessRights; /* Access rights for print servers */ -- cgit From a045dd063d24d004f66c3b11ca11ebf665639971 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 21:16:45 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 236 +++++++++++++++++++++++++++++++++++++++++-- librpc/gen_ndr/ndr_spoolss.h | 1 + librpc/gen_ndr/spoolss.h | 17 +++- 3 files changed, 247 insertions(+), 7 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 25c9dc49d7..5717da92d4 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -11356,6 +11356,9 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PrintProcessorDirectoryInfo(struct n break; } default: { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_PrintProcessorDirectoryInfo1(ndr, NDR_SCALARS, &r->info1)); break; } } @@ -11390,6 +11393,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PrintProcessorDirectoryInfo(struct n break; } default: { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_PrintProcessorDirectoryInfo1(ndr, NDR_SCALARS, &r->info1)); break; } } @@ -11420,6 +11426,7 @@ _PUBLIC_ void ndr_print_spoolss_PrintProcessorDirectoryInfo(struct ndr_print *nd break; default: + ndr_print_spoolss_PrintProcessorDirectoryInfo1(ndr, "info1", &r->info1); break; } @@ -12271,7 +12278,7 @@ static enum ndr_err_code ndr_push_spoolss_FormInfo2(struct ndr_push *ndr, int nd NDR_CHECK(ndr_push_spoolss_FormArea(ndr, NDR_SCALARS, &r->area)); { uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_relative_ptr1(ndr, r->keyword)); ndr->flags = _flags_save_string; } @@ -12303,7 +12310,7 @@ static enum ndr_err_code ndr_push_spoolss_FormInfo2(struct ndr_push *ndr, int nd } { uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); if (r->keyword) { NDR_CHECK(ndr_push_relative_ptr2(ndr, r->keyword)); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->keyword)); @@ -12361,7 +12368,7 @@ static enum ndr_err_code ndr_pull_spoolss_FormInfo2(struct ndr_pull *ndr, int nd NDR_CHECK(ndr_pull_spoolss_FormArea(ndr, NDR_SCALARS, &r->area)); { uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_keyword)); if (_ptr_keyword) { NDR_PULL_ALLOC(ndr, r->keyword); @@ -12417,7 +12424,7 @@ static enum ndr_err_code ndr_pull_spoolss_FormInfo2(struct ndr_pull *ndr, int nd } { uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); if (r->keyword) { uint32_t _relative_save_offset; _relative_save_offset = ndr->offset; @@ -12683,6 +12690,183 @@ _PUBLIC_ void ndr_print_spoolss_AddFormInfo1(struct ndr_print *ndr, const char * ndr->depth--; } +static enum ndr_err_code ndr_push_spoolss_AddFormInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_AddFormInfo2 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_spoolss_FormFlags(ndr, NDR_SCALARS, r->flags)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->form_name)); + NDR_CHECK(ndr_push_spoolss_FormSize(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_push_spoolss_FormArea(ndr, NDR_SCALARS, &r->area)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->keyword)); + NDR_CHECK(ndr_push_spoolss_FormStringType(ndr, NDR_SCALARS, r->string_type)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->mui_dll)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ressource_id)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->display_name)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->lang_id)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->form_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->form_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->form_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->form_name, ndr_charset_length(r->form_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->keyword) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->keyword, CH_DOS))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->keyword, CH_DOS))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->keyword, ndr_charset_length(r->keyword, CH_DOS), sizeof(uint8_t), CH_DOS)); + } + if (r->mui_dll) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->mui_dll, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->mui_dll, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->mui_dll, ndr_charset_length(r->mui_dll, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->display_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->display_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->display_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->display_name, ndr_charset_length(r->display_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_AddFormInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_AddFormInfo2 *r) +{ + uint32_t _ptr_form_name; + TALLOC_CTX *_mem_save_form_name_0; + uint32_t _ptr_keyword; + TALLOC_CTX *_mem_save_keyword_0; + uint32_t _ptr_mui_dll; + TALLOC_CTX *_mem_save_mui_dll_0; + uint32_t _ptr_display_name; + TALLOC_CTX *_mem_save_display_name_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_spoolss_FormFlags(ndr, NDR_SCALARS, &r->flags)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_form_name)); + if (_ptr_form_name) { + NDR_PULL_ALLOC(ndr, r->form_name); + } else { + r->form_name = NULL; + } + NDR_CHECK(ndr_pull_spoolss_FormSize(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_spoolss_FormArea(ndr, NDR_SCALARS, &r->area)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_keyword)); + if (_ptr_keyword) { + NDR_PULL_ALLOC(ndr, r->keyword); + } else { + r->keyword = NULL; + } + NDR_CHECK(ndr_pull_spoolss_FormStringType(ndr, NDR_SCALARS, &r->string_type)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_mui_dll)); + if (_ptr_mui_dll) { + NDR_PULL_ALLOC(ndr, r->mui_dll); + } else { + r->mui_dll = NULL; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ressource_id)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_display_name)); + if (_ptr_display_name) { + NDR_PULL_ALLOC(ndr, r->display_name); + } else { + r->display_name = NULL; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->lang_id)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->form_name) { + _mem_save_form_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->form_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->form_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->form_name)); + if (ndr_get_array_length(ndr, &r->form_name) > ndr_get_array_size(ndr, &r->form_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->form_name), ndr_get_array_length(ndr, &r->form_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->form_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->form_name, ndr_get_array_length(ndr, &r->form_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_form_name_0, 0); + } + if (r->keyword) { + _mem_save_keyword_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->keyword, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->keyword)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->keyword)); + if (ndr_get_array_length(ndr, &r->keyword) > ndr_get_array_size(ndr, &r->keyword)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->keyword), ndr_get_array_length(ndr, &r->keyword)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->keyword), sizeof(uint8_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->keyword, ndr_get_array_length(ndr, &r->keyword), sizeof(uint8_t), CH_DOS)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_keyword_0, 0); + } + if (r->mui_dll) { + _mem_save_mui_dll_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->mui_dll, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->mui_dll)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->mui_dll)); + if (ndr_get_array_length(ndr, &r->mui_dll) > ndr_get_array_size(ndr, &r->mui_dll)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->mui_dll), ndr_get_array_length(ndr, &r->mui_dll)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->mui_dll), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->mui_dll, ndr_get_array_length(ndr, &r->mui_dll), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_mui_dll_0, 0); + } + if (r->display_name) { + _mem_save_display_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->display_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->display_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->display_name)); + if (ndr_get_array_length(ndr, &r->display_name) > ndr_get_array_size(ndr, &r->display_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->display_name), ndr_get_array_length(ndr, &r->display_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->display_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->display_name, ndr_get_array_length(ndr, &r->display_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_display_name_0, 0); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_AddFormInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_AddFormInfo2 *r) +{ + ndr_print_struct(ndr, name, "spoolss_AddFormInfo2"); + ndr->depth++; + ndr_print_spoolss_FormFlags(ndr, "flags", r->flags); + ndr_print_ptr(ndr, "form_name", r->form_name); + ndr->depth++; + if (r->form_name) { + ndr_print_string(ndr, "form_name", r->form_name); + } + ndr->depth--; + ndr_print_spoolss_FormSize(ndr, "size", &r->size); + ndr_print_spoolss_FormArea(ndr, "area", &r->area); + ndr_print_ptr(ndr, "keyword", r->keyword); + ndr->depth++; + if (r->keyword) { + ndr_print_string(ndr, "keyword", r->keyword); + } + ndr->depth--; + ndr_print_spoolss_FormStringType(ndr, "string_type", r->string_type); + ndr_print_ptr(ndr, "mui_dll", r->mui_dll); + ndr->depth++; + if (r->mui_dll) { + ndr_print_string(ndr, "mui_dll", r->mui_dll); + } + ndr->depth--; + ndr_print_uint32(ndr, "ressource_id", r->ressource_id); + ndr_print_ptr(ndr, "display_name", r->display_name); + ndr->depth++; + if (r->display_name) { + ndr_print_string(ndr, "display_name", r->display_name); + } + ndr->depth--; + ndr_print_uint32(ndr, "lang_id", r->lang_id); + ndr->depth--; +} + static enum ndr_err_code ndr_push_spoolss_AddFormInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_AddFormInfo *r) { if (ndr_flags & NDR_SCALARS) { @@ -12693,6 +12877,10 @@ static enum ndr_err_code ndr_push_spoolss_AddFormInfo(struct ndr_push *ndr, int NDR_CHECK(ndr_push_unique_ptr(ndr, r->info1)); break; } + case 2: { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->info2)); + break; } + default: return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } @@ -12706,6 +12894,12 @@ static enum ndr_err_code ndr_push_spoolss_AddFormInfo(struct ndr_push *ndr, int } break; + case 2: + if (r->info2) { + NDR_CHECK(ndr_push_spoolss_AddFormInfo2(ndr, NDR_SCALARS|NDR_BUFFERS, r->info2)); + } + break; + default: return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } @@ -12718,6 +12912,7 @@ static enum ndr_err_code ndr_pull_spoolss_AddFormInfo(struct ndr_pull *ndr, int int level; uint32_t _level; TALLOC_CTX *_mem_save_info1_0; + TALLOC_CTX *_mem_save_info2_0; level = ndr_pull_get_switch_value(ndr, r); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level)); @@ -12735,6 +12930,16 @@ static enum ndr_err_code ndr_pull_spoolss_AddFormInfo(struct ndr_pull *ndr, int } break; } + case 2: { + uint32_t _ptr_info2; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info2)); + if (_ptr_info2) { + NDR_PULL_ALLOC(ndr, r->info2); + } else { + r->info2 = NULL; + } + break; } + default: return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } @@ -12750,6 +12955,15 @@ static enum ndr_err_code ndr_pull_spoolss_AddFormInfo(struct ndr_pull *ndr, int } break; + case 2: + if (r->info2) { + _mem_save_info2_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info2, 0); + NDR_CHECK(ndr_pull_spoolss_AddFormInfo2(ndr, NDR_SCALARS|NDR_BUFFERS, r->info2)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info2_0, 0); + } + break; + default: return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } @@ -12772,6 +12986,15 @@ _PUBLIC_ void ndr_print_spoolss_AddFormInfo(struct ndr_print *ndr, const char *n ndr->depth--; break; + case 2: + ndr_print_ptr(ndr, "info2", r->info2); + ndr->depth++; + if (r->info2) { + ndr_print_spoolss_AddFormInfo2(ndr, "info2", r->info2); + } + ndr->depth--; + break; + default: ndr_print_bad_level(ndr, name, level); } @@ -14852,6 +15075,7 @@ _PUBLIC_ void ndr_print_spoolss_AccessRights(struct ndr_print *ndr, const char * ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_ACCESS_ADMINISTER", PRINTER_ACCESS_ADMINISTER, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_ACCESS_USE", PRINTER_ACCESS_USE, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_ACCESS_ADMINISTER", JOB_ACCESS_ADMINISTER, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_ACCESS_READ", JOB_ACCESS_READ, r); ndr->depth--; } @@ -17341,7 +17565,7 @@ static enum ndr_err_code ndr_push_spoolss_GetPrintProcessorDirectory(struct ndr_ struct ndr_push *_ndr_info; NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 4, r->in.offered)); NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->out.info, r->in.level)); - NDR_CHECK(ndr_push_spoolss_PrintProcessorDirectoryInfo(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->out.info)); + NDR_CHECK(ndr_push_spoolss_PrintProcessorDirectoryInfo(_ndr_info, NDR_SCALARS, r->out.info)); NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 4, r->in.offered)); } } @@ -17435,7 +17659,7 @@ static enum ndr_err_code ndr_pull_spoolss_GetPrintProcessorDirectory(struct ndr_ struct ndr_pull *_ndr_info; NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 4, r->in.offered)); NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->out.info, r->in.level)); - NDR_CHECK(ndr_pull_spoolss_PrintProcessorDirectoryInfo(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->out.info)); + NDR_CHECK(ndr_pull_spoolss_PrintProcessorDirectoryInfo(_ndr_info, NDR_SCALARS, r->out.info)); NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 4, r->in.offered)); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index 5ecadc04d6..2e877542a4 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -351,6 +351,7 @@ enum ndr_err_code ndr_pull_spoolss_FormInfo(struct ndr_pull *ndr, int ndr_flags, void ndr_print_spoolss_FormInfo(struct ndr_print *ndr, const char *name, const union spoolss_FormInfo *r); size_t ndr_size_spoolss_FormInfo(const union spoolss_FormInfo *r, uint32_t level, struct smb_iconv_convenience *ic, int flags); void ndr_print_spoolss_AddFormInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_AddFormInfo1 *r); +void ndr_print_spoolss_AddFormInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_AddFormInfo2 *r); void ndr_print_spoolss_AddFormInfo(struct ndr_print *ndr, const char *name, const union spoolss_AddFormInfo *r); void ndr_print_spoolss_PortInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfo1 *r); void ndr_print_spoolss_PortType(struct ndr_print *ndr, const char *name, uint32_t r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 4ecb2a71b6..e758153ca9 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -970,7 +970,7 @@ struct spoolss_FormInfo2 { const char * form_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ struct spoolss_FormSize size; struct spoolss_FormArea area; - const char * keyword;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * keyword;/* [relative,flag(LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM)] */ uint32_t string_type; const char * mui_dll;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ uint32_t ressource_id; @@ -990,8 +990,22 @@ struct spoolss_AddFormInfo1 { struct spoolss_FormArea area; }; +struct spoolss_AddFormInfo2 { + enum spoolss_FormFlags flags; + const char *form_name;/* [unique,charset(UTF16)] */ + struct spoolss_FormSize size; + struct spoolss_FormArea area; + const char *keyword;/* [unique,charset(DOS)] */ + uint32_t string_type; + const char *mui_dll;/* [unique,charset(UTF16)] */ + uint32_t ressource_id; + const char *display_name;/* [unique,charset(UTF16)] */ + uint32_t lang_id; +}; + union spoolss_AddFormInfo { struct spoolss_AddFormInfo1 *info1;/* [unique,case] */ + struct spoolss_AddFormInfo2 *info2;/* [unique,case(2)] */ }/* [switch_type(uint32)] */; struct spoolss_PortInfo1 { @@ -1248,6 +1262,7 @@ struct spoolss_UserLevelCtr { #define PRINTER_ACCESS_ADMINISTER ( 0x00000004 ) #define PRINTER_ACCESS_USE ( 0x00000008 ) #define JOB_ACCESS_ADMINISTER ( 0x00000010 ) +#define JOB_ACCESS_READ ( 0x00000020 ) /* bitmap spoolss_DeleteDriverFlags */ #define DPD_DELETE_UNUSED_FILES ( 0x00000001 ) -- cgit From 666cc916ebea618fbf7bfed99dbfff38326189fa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 16:17:44 +0100 Subject: s4-smbtorture: add test_GetPrintProcessorDirectory to RPC-SPOOLSS. Guenther --- source4/torture/rpc/spoolss.c | 64 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index de600e8fb3..f8a66e7753 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -168,6 +168,69 @@ static bool test_EnumPorts(struct torture_context *tctx, return true; } +static bool test_GetPrintProcessorDirectory(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct test_spoolss_context *ctx) +{ + NTSTATUS status; + struct spoolss_GetPrintProcessorDirectory r; + struct { + uint16_t level; + const char *server; + } levels[] = {{ + .level = 1, + .server = NULL + },{ + .level = 1, + .server = "" + },{ + .level = 78, + .server = "" + },{ + .level = 1, + .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)) + },{ + .level = 1024, + .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)) + } + }; + int i; + uint32_t needed; + + for (i=0;iserver_handle, true); ret &= test_EnumPorts(torture, p, ctx); ret &= test_GetPrinterDriverDirectory(torture, p, ctx); + ret &= test_GetPrintProcessorDirectory(torture, p, ctx); ret &= test_EnumPrinterDrivers(torture, p, ctx); ret &= test_EnumMonitors(torture, p, ctx); ret &= test_EnumPrintProcessors(torture, p, ctx); -- cgit From 6cd30a351a13822a557f20de3abe04bd8b2e3112 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 21:10:44 +0100 Subject: s4-smbtorture: expand RPC-SPOOLSS enumform and getform tests for level 2 forms. Guenther --- source4/torture/rpc/spoolss.c | 74 ++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index f8a66e7753..04c9768ea8 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -742,7 +742,8 @@ static bool test_ClosePrinter(struct torture_context *tctx, static bool test_GetForm(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle, - const char *form_name) + const char *form_name, + uint32_t level) { NTSTATUS status; struct spoolss_GetForm r; @@ -750,12 +751,12 @@ static bool test_GetForm(struct torture_context *tctx, r.in.handle = handle; r.in.form_name = form_name; - r.in.level = 1; + r.in.level = level; r.in.buffer = NULL; r.in.offered = 0; r.out.needed = &needed; - torture_comment(tctx, "Testing GetForm\n"); + torture_comment(tctx, "Testing GetForm level %d\n", r.in.level); status = dcerpc_spoolss_GetForm(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetForm failed"); @@ -787,45 +788,54 @@ static bool test_EnumForms(struct torture_context *tctx, bool ret = true; uint32_t needed; uint32_t count; + uint32_t levels[] = { 1, 2 }; + int i; - r.in.handle = handle; - r.in.level = 1; - r.in.buffer = NULL; - r.in.offered = 0; - r.out.needed = &needed; - r.out.count = &count; + for (i=0; i Date: Wed, 25 Feb 2009 20:48:55 +0100 Subject: s3-spoolss: JOB_ACCESS_READ has moved to idl. Guenther --- source3/include/rpc_spoolss.h | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index c494fdd6bf..1880331590 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -123,7 +123,6 @@ #define PRINTER_STATUS_OK 0x00000000 -#define JOB_ACCESS_READ 0x00000020 /* JOB status codes. */ -- cgit From 03efdcb7cb55f61d2b8cf419b25ed6d1eac1d3af Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 21:08:13 +0100 Subject: s3-spoolss: make us pass the RPC-SPOOLSS torture test w.r.t. directory calls. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 62 ++++++++++++++----------------------- 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 62301c001b..2f89775101 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -8180,28 +8180,21 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p, return WERR_INVALID_PARAM; } - if (r->in.offered > MAX_RPC_DATA_SIZE) { - return WERR_INVALID_PARAM; - } - - DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n")); + DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n", + r->in.level)); *r->out.needed = 0; - switch (r->in.level) { - case 1: - werror = getprinterdriverdir_level_1(p->mem_ctx, - r->in.server, - r->in.environment, - &r->out.info->info1, - r->in.offered, - r->out.needed); - if (!W_ERROR_IS_OK(werror)) { - TALLOC_FREE(r->out.info); - } - break; - default: - return WERR_UNKNOWN_LEVEL; + /* r->in.level is ignored */ + + werror = getprinterdriverdir_level_1(p->mem_ctx, + r->in.server, + r->in.environment, + &r->out.info->info1, + r->in.offered, + r->out.needed); + if (!W_ERROR_IS_OK(werror)) { + TALLOC_FREE(r->out.info); } return werror; @@ -9834,28 +9827,21 @@ WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p, return WERR_INVALID_PARAM; } - if (r->in.offered > MAX_RPC_DATA_SIZE) { - return WERR_INVALID_PARAM; - } - - DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n")); + DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n", + r->in.level)); *r->out.needed = 0; - switch (r->in.level) { - case 1: - result = getprintprocessordirectory_level_1(p->mem_ctx, - r->in.server, - r->in.environment, - &r->out.info->info1, - r->in.offered, - r->out.needed); - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(r->out.info); - } - break; - default: - result = WERR_UNKNOWN_LEVEL; + /* r->in.level is ignored */ + + result = getprintprocessordirectory_level_1(p->mem_ctx, + r->in.server, + r->in.environment, + &r->out.info->info1, + r->in.offered, + r->out.needed); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(r->out.info); } return result; -- cgit From d86cb9b52d8cdaa03f856665f56278836e6336d3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 20:50:34 +0100 Subject: s3-rpcclient: support level 2 in spoolss_addform. Guenther --- source3/rpcclient/cmd_spoolss.c | 54 ++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 51fcaaa54c..79cde704d2 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1814,11 +1814,13 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c const char *printername; union spoolss_AddFormInfo info; struct spoolss_AddFormInfo1 info1; + struct spoolss_AddFormInfo2 info2; + uint32_t level = 1; /* Parse the command arguments */ - if (argc != 3) { - printf ("Usage: %s \n", argv[0]); + if (argc < 3 || argc > 5) { + printf ("Usage: %s [level]\n", argv[0]); return WERR_OK; } @@ -1835,23 +1837,51 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c /* Dummy up some values for the form data */ - info1.flags = FORM_USER; - info1.form_name = argv[2]; - info1.size.width = 100; - info1.size.height = 100; - info1.area.left = 0; - info1.area.top = 10; - info1.area.right = 20; - info1.area.bottom = 30; + if (argc == 4) { + level = atoi(argv[3]); + } - info.info1 = &info1; + switch (level) { + case 1: + info1.flags = FORM_USER; + info1.form_name = argv[2]; + info1.size.width = 100; + info1.size.height = 100; + info1.area.left = 0; + info1.area.top = 10; + info1.area.right = 20; + info1.area.bottom = 30; + + info.info1 = &info1; + + break; + case 2: + info2.flags = FORM_USER; + info2.form_name = argv[2]; + info2.size.width = 100; + info2.size.height = 100; + info2.area.left = 0; + info2.area.top = 10; + info2.area.right = 20; + info2.area.bottom = 30; + info2.keyword = argv[2]; + info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE; + info2.mui_dll = NULL; + info2.ressource_id = 0; + info2.display_name = argv[2]; + info2.lang_id = 0; + + info.info2 = &info2; + + break; + } /* Add the form */ status = rpccli_spoolss_AddForm(cli, mem_ctx, &handle, - 1, + level, info, &werror); -- cgit From 3d7cde5dd3603ba3a7e78e8ca9a28d5bbf816b80 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2009 12:53:45 -0800 Subject: Fix bug in processing of open modes in POSIX open. Was missing case of "If file exists open. If file doesn't exist error." Damn damn damn. CIFSFS client will have to have fallback cases for this error for a long time. Jeremy. --- source3/smbd/trans2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 433b8a008d..369830b086 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6423,6 +6423,8 @@ static NTSTATUS smb_posix_open(connection_struct *conn, create_disp = FILE_OVERWRITE_IF; } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) { create_disp = FILE_OPEN_IF; + } else if (wire_open_mode == 0) { + create_disp = FILE_OPEN; } else { DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n", (unsigned int)wire_open_mode )); -- cgit From bfc7ec9e4a35e8ad64205e56cd0e621b41740efb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2009 13:00:44 -0800 Subject: Make test for open modes more robust against other bits. Jeremy. --- source3/smbd/trans2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 369830b086..ee1dda98b2 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6423,7 +6423,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn, create_disp = FILE_OVERWRITE_IF; } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) { create_disp = FILE_OPEN_IF; - } else if (wire_open_mode == 0) { + } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC)) == 0) { create_disp = FILE_OPEN; } else { DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n", -- cgit From a4e570e3cedf284ee83853415176e4dcccc105cb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 22:10:21 +0100 Subject: s3-rpcclient: add test command to call netr_LogonGetCapabilities (for bug #6100). Guenther --- source3/rpcclient/cmd_netlogon.c | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 9955d2d3fa..45df488018 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -1107,6 +1107,49 @@ static NTSTATUS cmd_netlogon_database_redo(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_netlogon_capabilities(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + union netr_Capabilities capabilities; + uint32_t level = 1; + + if (argc > 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return NT_STATUS_OK; + } + + if (argc == 2) { + level = atoi(argv[1]); + } + +#if 0 + netlogon_creds_client_step(cli->dc, &credential); +#else + ZERO_STRUCT(credential); +#endif + + status = rpccli_netr_LogonGetCapabilities(cli, mem_ctx, + cli->desthost, + global_myname(), + &credential, + &return_authenticator, + level, + &capabilities); +#if 0 + if (!netlogon_creds_client_check(cli->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } +#endif + + return status; +} + /* List of commands exported by this module */ struct cmd_set netlogon_commands[] = { @@ -1134,6 +1177,7 @@ struct cmd_set netlogon_commands[] = { { "netrenumtrusteddomainsex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomainsex, &ndr_table_netlogon.syntax_id, NULL, "Enumerate trusted domains", "" }, { "getdcsitecoverage", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcsitecoverage, &ndr_table_netlogon.syntax_id, NULL, "Get the Site-Coverage from a DC", "" }, { "database_redo", RPC_RTYPE_NTSTATUS, cmd_netlogon_database_redo, NULL, &ndr_table_netlogon.syntax_id, NULL, "Replicate single object from a DC", "" }, + { "capabilities", RPC_RTYPE_NTSTATUS, cmd_netlogon_capabilities, NULL, &ndr_table_netlogon.syntax_id, NULL, "Return Capabilities", "" }, { NULL } }; -- cgit From 76ca297ecfd1086b38487ac8f53a8392a4a38ad6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2009 13:46:21 -0800 Subject: Fix use of streams modules with CIFSFS client. Jeremy. --- source3/modules/vfs_streams_depot.c | 14 ++++++++++++-- source3/modules/vfs_streams_xattr.c | 15 +++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index 9329be7a9c..023d2b9ec0 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -494,7 +494,13 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) * We potentially need to delete the per-inode streams directory */ - if (SMB_VFS_NEXT_STAT(handle, fname, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_NEXT_LSTAT(handle, fname, &sbuf); + } else { + ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + } + + if (ret == -1) { return -1; } @@ -678,7 +684,11 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle, if (is_ntfs_stream_name(fname)) { return NT_STATUS_INVALID_PARAMETER; } - ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_NEXT_LSTAT(handle, fname, &sbuf); + } else { + ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + } } if (ret == -1) { diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 77ffff5fb5..3d5478d7a2 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -135,6 +135,7 @@ static bool streams_xattr_recheck(struct stream_io *sio) static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf) { + int ret = -1; struct stream_io *io = (struct stream_io *) VFS_FETCH_FSP_EXTENSION(handle, fsp); @@ -148,7 +149,13 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, return -1; } - if (SMB_VFS_STAT(handle->conn, io->base, sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, io->base, sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, io->base, sbuf); + } + + if (ret == -1) { return -1; } @@ -719,7 +726,11 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle, if (is_ntfs_stream_name(fname)) { return NT_STATUS_INVALID_PARAMETER; } - ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + } } if (ret == -1) { -- cgit From 01493737c88c0056ca3da5faf43b7bc9b9a2fbcb Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 23 Feb 2009 14:51:17 -0800 Subject: s3 OneFS: Add .snapshot directory configuration handling --- source3/modules/onefs.h | 32 ++++++++- source3/modules/onefs_streams.c | 2 +- source3/modules/onefs_system.c | 50 ++++++++++++++ source3/modules/vfs_onefs.c | 144 +++++++++++++++++++++++++++++++++------- 4 files changed, 201 insertions(+), 27 deletions(-) diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index 418e13d9d2..a0f4fe37de 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -57,6 +57,16 @@ enum onefs_acl_wire_format #define PARM_CTIME_NOW_DEFAULT NULL #define PARM_CTIME_SLOP "ctime now slop" #define PARM_CTIME_SLOP_DEFAULT 0 +#define PARM_DOT_SNAP_CHILD_ACCESSIBLE "dot snap child accessible" +#define PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT true +#define PARM_DOT_SNAP_CHILD_VISIBLE "dot snap child visible" +#define PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT false +#define PARM_DOT_SNAP_ROOT_ACCESSIBLE "dot snap root accessible" +#define PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT true +#define PARM_DOT_SNAP_ROOT_VISIBLE "dot snap root visible" +#define PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT true +#define PARM_DOT_SNAP_TILDE "dot snap tilde" +#define PARM_DOT_SNAP_TILDE_DEFAULT true #define PARM_IGNORE_SACLS "ignore sacls" #define PARM_IGNORE_SACLS_DEFAULT false #define PARM_MTIME_NOW "mtime now files" @@ -99,9 +109,9 @@ enum onefs_acl_wire_format #define ONEFS_VFS_CONFIG_FAKETIMESTAMPS 0x00000001 -struct onefs_vfs_config +struct onefs_vfs_share_config { - int32 init_flags; + uint32_t init_flags; /* data for fake timestamps */ int atime_slop; @@ -127,6 +137,18 @@ struct onefs_vfs_config name_compare_entry *atime_static_list; }; +struct onefs_vfs_global_config +{ + uint32_t init_flags; + + /* Snapshot options */ + bool dot_snap_child_accessible; + bool dot_snap_child_visible; + bool dot_snap_root_accessible; + bool dot_snap_root_visible; + bool dot_snap_tilde; +}; + /* * vfs interface handlers */ @@ -240,7 +262,7 @@ NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, char **pbase, char **pstream); bool onefs_get_config(int snum, int config_type, - struct onefs_vfs_config *cfg); + struct onefs_vfs_share_config *cfg); int onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp); @@ -269,4 +291,8 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, size_t count); +void onefs_sys_config_enc(void); +void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config); +void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config); + #endif /* _ONEFS_H */ diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 2dcd8891eb..6e2794399d 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -230,7 +230,7 @@ static void merge_stat(SMB_STRUCT_STAT *stream_sbuf, static void onefs_adjust_stat_time(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) { - struct onefs_vfs_config cfg; + struct onefs_vfs_share_config cfg; struct timeval tv_now = {0, 0}; bool static_mtime = False; bool static_atime = False; diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 518a398154..43ebed8d44 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -656,3 +656,53 @@ out: return ret; } + +/** + * Set the per-process encoding, ignoring errors. + */ +void onefs_sys_config_enc(void) +{ + int ret; + + ret = enc_set_proc(ENC_UTF8); + if (ret) { + DEBUG(0, ("Setting process encoding failed: %s", + strerror(errno))); + } +} + +/** + * Set the per-process .snpashot directory options, ignoring errors. + */ +void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config) +{ + struct ifs_dotsnap_options dso; + int ret; + + dso.per_proc = 1; + dso.sub_accessible = global_config->dot_snap_child_accessible; + dso.sub_visible = global_config->dot_snap_child_visible; + dso.root_accessible = global_config->dot_snap_root_accessible; + dso.root_visible = global_config->dot_snap_root_visible; + + ret = ifs_set_dotsnap_options(&dso); + if (ret) { + DEBUG(0, ("Setting snapshot visibility/accessibility " + "failed: %s", strerror(errno))); + } +} + +/** + * Set the per-process flag saying whether or not to accept ~snapshot + * as an alternative name for .snapshot directories. + */ +void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config) +{ + int ret; + + ret = ifs_tilde_snapshot(global_config->dot_snap_tilde); + if (ret) { + DEBUG(0, ("Setting snapshot tilde failed: %s", + strerror(errno))); + } +} diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index 60c2c977a4..f81134909f 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -26,14 +26,14 @@ #define ONEFS_DATA_FASTBUF 10 -struct onefs_vfs_config share_config[ONEFS_DATA_FASTBUF]; -struct onefs_vfs_config *pshare_config; +struct onefs_vfs_share_config vfs_share_config[ONEFS_DATA_FASTBUF]; +struct onefs_vfs_share_config *pvfs_share_config; -static void onefs_load_faketimestamp_config(struct vfs_handle_struct *handle, - struct onefs_vfs_config *cfg) +static void onefs_load_faketimestamp_config(struct connection_struct *conn, + struct onefs_vfs_share_config *cfg) { const char **parm; - int snum = SNUM(handle->conn); + int snum = SNUM(conn); parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW, PARM_ATIME_NOW_DEFAULT); @@ -83,46 +83,141 @@ static void onefs_load_faketimestamp_config(struct vfs_handle_struct *handle, PARM_MTIME_SLOP_DEFAULT); } +/** + * Set onefs-specific vfs global config parameters. + * + * Since changes in these parameters require calling syscalls, we only want to + * call them when the configuration actually changes. + */ +static void onefs_load_global_config(connection_struct *conn) +{ + static struct onefs_vfs_global_config global_config; + bool dot_snap_child_accessible; + bool dot_snap_child_visible; + bool dot_snap_root_accessible; + bool dot_snap_root_visible; + bool dot_snap_tilde; + bool reconfig_dso = false; + bool reconfig_tilde = false; + + /* Check if this is the first time setting the config options. */ + if (!(global_config.init_flags & ONEFS_VFS_CONFIG_INITIALIZED)) { + global_config.init_flags |= ONEFS_VFS_CONFIG_INITIALIZED; + + /* Set process encoding */ + onefs_sys_config_enc(); + + reconfig_dso = true; + reconfig_tilde = true; + } -static int onefs_load_config(struct vfs_handle_struct *handle) + /* Get the dot snap options from the conf. */ + dot_snap_child_accessible = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_CHILD_ACCESSIBLE, + PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT); + dot_snap_child_visible = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_CHILD_VISIBLE, + PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT); + dot_snap_root_accessible = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_ROOT_ACCESSIBLE, + PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT); + dot_snap_root_visible = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_ROOT_VISIBLE, + PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT); + dot_snap_tilde = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_TILDE, + PARM_DOT_SNAP_TILDE_DEFAULT); + + /* Check if any of the dot snap options need updating. */ + if (dot_snap_child_accessible != + global_config.dot_snap_child_accessible) { + global_config.dot_snap_child_accessible = + dot_snap_child_accessible; + reconfig_dso = true; + } + if (dot_snap_child_visible != + global_config.dot_snap_child_visible) { + global_config.dot_snap_child_visible = + dot_snap_child_visible; + reconfig_dso = true; + } + if (dot_snap_root_accessible != + global_config.dot_snap_root_accessible) { + global_config.dot_snap_root_accessible = + dot_snap_root_accessible; + reconfig_dso = true; + } + if (dot_snap_root_visible != + global_config.dot_snap_root_visible) { + global_config.dot_snap_root_visible = + dot_snap_root_visible; + reconfig_dso = true; + } + if (dot_snap_tilde != global_config.dot_snap_tilde) { + global_config.dot_snap_tilde = dot_snap_tilde; + reconfig_tilde = true; + } + + /* If a dot snap option has changed update the process. */ + if (reconfig_dso) { + onefs_sys_config_snap_opt(&global_config); + } + + /* If the dot snap tilde option has changed update the process. */ + if (reconfig_tilde) { + onefs_sys_config_tilde(&global_config); + } +} + +static int onefs_load_config(connection_struct *conn) { - int snum = SNUM(handle->conn); + int snum = SNUM(conn); int share_count = lp_numservices(); - if (!pshare_config) { + /* Share config */ + if (!pvfs_share_config) { if (share_count <= ONEFS_DATA_FASTBUF) - pshare_config = share_config; + pvfs_share_config = vfs_share_config; else { - pshare_config = - SMB_MALLOC_ARRAY(struct onefs_vfs_config, + pvfs_share_config = + SMB_MALLOC_ARRAY(struct onefs_vfs_share_config, share_count); - if (!pshare_config) { + if (!pvfs_share_config) { errno = ENOMEM; return -1; } - memset(pshare_config, 0, - (sizeof(struct onefs_vfs_config) * share_count)); + memset(pvfs_share_config, 0, + (sizeof(struct onefs_vfs_share_config) * + share_count)); } } - if ((pshare_config[snum].init_flags & + if ((pvfs_share_config[snum].init_flags & ONEFS_VFS_CONFIG_INITIALIZED) == 0) { - pshare_config[snum].init_flags = + pvfs_share_config[snum].init_flags = ONEFS_VFS_CONFIG_INITIALIZED; - onefs_load_faketimestamp_config(handle, - &pshare_config[snum]); + onefs_load_faketimestamp_config(conn, + &pvfs_share_config[snum]); } + /* Global config */ + onefs_load_global_config(conn); + return 0; } bool onefs_get_config(int snum, int config_type, - struct onefs_vfs_config *cfg) + struct onefs_vfs_share_config *cfg) { - if (share_config[snum].init_flags & config_type) - *cfg = share_config[snum]; + if (vfs_share_config[snum].init_flags & config_type) + *cfg = vfs_share_config[snum]; else return false; @@ -132,10 +227,13 @@ bool onefs_get_config(int snum, int config_type, static int onefs_connect(struct vfs_handle_struct *handle, const char *service, const char *user) { - int ret = onefs_load_config(handle); + int ret; - if (ret) + ret = onefs_load_config(handle->conn); + if (ret) { + DEBUG(3, ("Load config failed: %s\n", strerror(errno))); return ret; + } return SMB_VFS_NEXT_CONNECT(handle, service, user); } -- cgit From 7f33b947e3c770f96f46fc9466376cd3c7825cd4 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 14:45:46 -0800 Subject: s3: Refactor and cleanup the error paths in dump_core_setup --- source3/lib/fault.c | 91 ++++++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/source3/lib/fault.c b/source3/lib/fault.c index 8c4a45bbc9..cf5a94b6bd 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -87,6 +87,47 @@ void fault_setup(void (*fn)(void *)) #endif } +/** + * Build up the default corepath as "/cores/" + */ +static char *get_default_corepath(const char *logbase, const char *progname) +{ + char *tmp_corepath; + + /* Setup core dir in logbase. */ + tmp_corepath = talloc_asprintf(NULL, "%s/cores", logbase); + if (!tmp_corepath) + return NULL; + + if ((mkdir(tmp_corepath, 0700) == -1) && errno != EEXIST) + goto err_out; + + if (chmod(tmp_corepath, 0700) == -1) + goto err_out; + + talloc_free(tmp_corepath); + + /* Setup progname-specific core subdir */ + tmp_corepath = talloc_asprintf(NULL, "%s/cores/%s", logbase, progname); + if (!tmp_corepath) + return NULL; + + if (mkdir(tmp_corepath, 0700) == -1 && errno != EEXIST) + goto err_out; + + if (chown(tmp_corepath, getuid(), getgid()) == -1) + goto err_out; + + if (chmod(tmp_corepath, 0700) == -1) + goto err_out; + + return tmp_corepath; + + err_out: + talloc_free(tmp_corepath); + return NULL; +} + /******************************************************************* make all the preparations to safely dump a core file ********************************************************************/ @@ -104,7 +145,7 @@ void dump_core_setup(const char *progname) *end = '\0'; } } else { - /* We will end up here is the log file is given on the command + /* We will end up here if the log file is given on the command * line by the -l option but the "log file" option is not set * in smb.conf. */ @@ -115,49 +156,13 @@ void dump_core_setup(const char *progname) SMB_ASSERT(progname != NULL); - if (asprintf(&corepath, "%s/cores", logbase) < 0) { - SAFE_FREE(logbase); - return; - } - if (mkdir(corepath,0700) == -1) { - if (errno != EEXIST) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; - } - } - if (chmod(corepath,0700) == -1) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; + corepath = get_default_corepath(logbase, progname); + if (!corepath) { + DEBUG(0, ("Unable to setup corepath for %s: %s\n", progname, + strerror(errno))); + goto out; } - SAFE_FREE(corepath); - if (asprintf(&corepath, "%s/cores/%s", - logbase, progname) < 0) { - SAFE_FREE(logbase); - return; - } - if (mkdir(corepath,0700) == -1) { - if (errno != EEXIST) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; - } - } - - if (chown(corepath,getuid(),getgid()) == -1) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; - } - if (chmod(corepath,0700) == -1) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; - } - - SAFE_FREE(logbase); #ifdef HAVE_GETRLIMIT #ifdef RLIMIT_CORE @@ -184,6 +189,8 @@ void dump_core_setup(const char *progname) /* FIXME: if we have a core-plus-pid facility, configurably set * this up here. */ + out: + SAFE_FREE(logbase); } void dump_core(void) -- cgit From 95e428e2279b706ac590ffb964fda07fd1ee2200 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 16:42:18 -0800 Subject: s3: Report the correct path when dumping core on FreeBSD Utilize the kern.corefile sysctl value on FreeBSD --- source3/lib/fault.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/source3/lib/fault.c b/source3/lib/fault.c index cf5a94b6bd..efd1dddfd4 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. Critical Fault handling Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Tim Prouty 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -128,6 +129,87 @@ static char *get_default_corepath(const char *logbase, const char *progname) return NULL; } +/** + * Get the FreeBSD corepath. + * + * On FreeBSD the current working directory is ignored when creating a core + * file. Instead the core directory is controlled via sysctl. This consults + * the value of "kern.corefile" so the correct corepath can be printed out + * before dump_core() calls abort. + */ +#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME)) +static char *get_freebsd_corepath(void) +{ + char *tmp_corepath = NULL; + char *end = NULL; + size_t len = 128; + int ret; + + /* Loop with increasing sizes so we don't allocate too much. */ + do { + if (len > 1024) { + goto err_out; + } + + tmp_corepath = (char *)talloc_realloc(NULL, tmp_corepath, + char, len); + if (!tmp_corepath) { + return NULL; + } + + ret = sysctlbyname("kern.corefile", tmp_corepath, &len, NULL, + 0); + if (ret == -1) { + if (errno != ENOMEM) { + DEBUG(0, ("sysctlbyname failed getting " + "kern.corefile %s\n", + strerror(errno))); + goto err_out; + } + + /* Not a large enough array, try a bigger one. */ + len = len << 1; + } + } while (ret == -1); + + /* Strip off the common filename expansion */ + if ((end = strrchr_m(tmp_corepath, '/'))) { + *end = '\0'; + } + + return tmp_corepath; + + err_out: + if (tmp_corepath) { + talloc_free(tmp_corepath); + } + return NULL; +} +#endif + +/** + * Try getting system-specific corepath if one exists. + * + * If the system doesn't define a corepath, then the default is used. + */ +static char *get_corepath(const char *logbase, const char *progname) +{ + char *tmp_corepath = NULL; + + /* @todo: Add support for the linux corepath. */ +#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME)) + tmp_corepath = get_freebsd_corepath(); +#endif + + /* If this has been set correctly, we're done. */ + if (tmp_corepath) { + return tmp_corepath; + } + + /* Fall back to the default. */ + return get_default_corepath(logbase, progname); +} + /******************************************************************* make all the preparations to safely dump a core file ********************************************************************/ @@ -156,7 +238,7 @@ void dump_core_setup(const char *progname) SMB_ASSERT(progname != NULL); - corepath = get_default_corepath(logbase, progname); + corepath = get_corepath(logbase, progname); if (!corepath) { DEBUG(0, ("Unable to setup corepath for %s: %s\n", progname, strerror(errno))); -- cgit From e17df483fbedb81aededdef5fbb6ae1d034bc2dd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Jan 2009 10:54:12 +0100 Subject: lib/tdb: if we know pwrite and pread are thread/fork safe tdb_reopen_all() should be a noop The reason for tdb_reopen_all() is that the seek pointer on fds are shared between parent and child. metze --- lib/tdb/common/open.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c index b19e4cea29..e58c8ca7ff 100644 --- a/lib/tdb/common/open.c +++ b/lib/tdb/common/open.c @@ -461,6 +461,10 @@ fail: /* reopen all tdb's */ int tdb_reopen_all(int parent_longlived) { +#if defined(LIBREPLACE_PREAD_NOT_REPLACED) && \ + defined(LIBREPLACE_PWRITE_NOT_REPLACED) + return 0; +#else struct tdb_context *tdb; for (tdb=tdbs; tdb; tdb = tdb->next) { @@ -483,6 +487,7 @@ int tdb_reopen_all(int parent_longlived) if (tdb_reopen(tdb) != 0) return -1; } +#endif return 0; } -- cgit From 228e75112ffe4124748e80d6571ddde4df22881f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 23:04:52 +0100 Subject: s4-spoolss: implement dcesrv_spoolss_GetPrintProcessorDirectory. Guenther --- source4/ntptr/ntptr.h | 3 ++ source4/ntptr/ntptr_interface.c | 9 ++++++ source4/ntptr/simple_ldb/ntptr_simple_ldb.c | 43 +++++++++++++++++++++++++++++ source4/rpc_server/spoolss/dcesrv_spoolss.c | 14 +++++++++- 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/source4/ntptr/ntptr.h b/source4/ntptr/ntptr.h index 24c467fe65..91817a202f 100644 --- a/source4/ntptr/ntptr.h +++ b/source4/ntptr/ntptr.h @@ -74,6 +74,7 @@ struct spoolss_EnumForms; struct spoolss_EnumPorts; struct spoolss_EnumPrintProcessors; struct spoolss_XcvData; +struct spoolss_GetPrintProcessorDirectory; /* the ntptr operations structure - contains function pointers to the backend implementations of each operation */ @@ -144,6 +145,8 @@ struct ntptr_ops { /* PrintProcessor functions */ WERROR (*EnumPrintProcessors)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, struct spoolss_EnumPrintProcessors *r); + WERROR (*GetPrintProcessorDirectory)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrintProcessorDirectory *r); /* Printer functions */ WERROR (*EnumPrinters)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, diff --git a/source4/ntptr/ntptr_interface.c b/source4/ntptr/ntptr_interface.c index 109a9f560b..b65a2e32cd 100644 --- a/source4/ntptr/ntptr_interface.c +++ b/source4/ntptr/ntptr_interface.c @@ -263,6 +263,15 @@ WERROR ntptr_EnumPrintProcessors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ct return ntptr->ops->EnumPrintProcessors(ntptr, mem_ctx, r); } +WERROR ntptr_GetPrintProcessorDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrintProcessorDirectory *r) +{ + if (!ntptr->ops->GetPrintProcessorDirectory) { + return WERR_NOT_SUPPORTED; + } + return ntptr->ops->GetPrintProcessorDirectory(ntptr, mem_ctx, r); +} + /* Printer functions */ WERROR ntptr_EnumPrinters(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, diff --git a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c index c570b03a35..459babce0e 100644 --- a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c +++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c @@ -750,6 +750,47 @@ static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CT return WERR_OK; } +static WERROR sptr_GetPrintProcessorDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrintProcessorDirectory *r) +{ + union spoolss_PrintProcessorDirectoryInfo *info; + const char *prefix; + const char *postfix; + + /* + * NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a + * are ignoring the r->in.level completely, so we do :-) + */ + + /* + * TODO: check the server name is ours + * - if it's a invalid UNC then return WERR_INVALID_NAME + * - if it's the wrong host name return WERR_INVALID_PARAM + * - if it's "" then we need to return a local WINDOWS path + */ + if (!r->in.server || !r->in.server[0]) { + prefix = "C:\\PRTPROCS"; + } else { + prefix = talloc_asprintf(mem_ctx, "%s\\prnproc$", r->in.server); + W_ERROR_HAVE_NO_MEMORY(prefix); + } + + if (r->in.environment && strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) { + postfix = "W32X86"; + } else { + return WERR_INVALID_ENVIRONMENT; + } + + info = talloc(mem_ctx, union spoolss_PrintProcessorDirectoryInfo); + W_ERROR_HAVE_NO_MEMORY(info); + + info->info1.directory_name = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix); + W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name); + + r->out.info = info; + return WERR_OK; +} + /* initialialise the simble ldb backend, registering ourselves with the ntptr subsystem @@ -793,6 +834,8 @@ static const struct ntptr_ops ntptr_simple_ldb_ops = { /* PrintProcessor functions */ /* .EnumPrintProcessors = sptr_EnumPrintProcessors, */ + .GetPrintProcessorDirectory = sptr_GetPrintProcessorDirectory, + /* Printer functions */ .EnumPrinters = sptr_EnumPrinters, .OpenPrinter = sptr_OpenPrinter, diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index 33c657cc1b..89b93bbaa4 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -454,7 +454,19 @@ static WERROR dcesrv_spoolss_EnumPrintProcessors(struct dcesrv_call_state *dce_c static WERROR dcesrv_spoolss_GetPrintProcessorDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct spoolss_GetPrintProcessorDirectory *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private_data, struct ntptr_context); + WERROR status; + struct smb_iconv_convenience *ic = lp_iconv_convenience(ntptr->lp_ctx); + + status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); + W_ERROR_NOT_OK_RETURN(status); + + status = ntptr_GetPrintProcessorDirectory(ntptr, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + + *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, ic, r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } -- cgit From 9b8bb1ad957f9c2d91e55ac6a27657cd8f6d4a14 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2009 14:12:51 -0800 Subject: Ensure ACL modules work with POSIX paths. Jeremy. --- source3/modules/vfs_acl_tdb.c | 89 ++++++++++++++++++++++++++++++++--------- source3/modules/vfs_acl_xattr.c | 12 +++++- 2 files changed, 79 insertions(+), 22 deletions(-) diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 909de9d7c8..5cd3e21594 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -186,20 +186,26 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, TDB_DATA data; struct file_id id; struct db_context *db; + int ret = -1; SMB_STRUCT_STAT sbuf; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return NT_STATUS_INTERNAL_DB_CORRUPTION); if (fsp && fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) { - return map_nt_error_from_unix(errno); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, name, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, name, &sbuf); } } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); /* For backwards compatibility only store the dev/inode. */ @@ -270,6 +276,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, TDB_DATA data; struct db_context *db; struct db_record *rec; + int ret = -1; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", (unsigned int)pblob->length, fsp->fsp_name)); @@ -278,14 +285,19 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, return NT_STATUS_INTERNAL_DB_CORRUPTION); if (fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf) == -1) { - return map_nt_error_from_unix(errno); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf); } } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); /* For backwards compatibility only store the dev/inode. */ @@ -316,6 +328,7 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, SMB_STRUCT_STAT sbuf; struct db_context *db; struct db_record *rec; + int ret = -1; DEBUG(10,("store_acl_blob_pathname: storing blob " "length %u on file %s\n", @@ -324,7 +337,13 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return NT_STATUS_INTERNAL_DB_CORRUPTION); - if (SMB_VFS_STAT(handle->conn, fname, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + } + + if (ret == -1) { return map_nt_error_from_unix(errno); } @@ -494,7 +513,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + } } if (ret == -1) { return map_nt_error_from_unix(errno); @@ -583,11 +606,17 @@ static int unlink_acl_tdb(vfs_handle_struct *handle, const char *path) { SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -626,11 +655,17 @@ static int rmdir_acl_tdb(vfs_handle_struct *handle, const char *path) SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -728,7 +763,11 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, return NT_STATUS_OK; } if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } @@ -813,11 +852,17 @@ static int sys_acl_set_file_tdb(vfs_handle_struct *handle, { SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -848,7 +893,11 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 7c78b506f0..f46e4683aa 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -381,7 +381,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + } } if (ret == -1) { return map_nt_error_from_unix(errno); @@ -559,7 +563,11 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, return NT_STATUS_OK; } if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } -- cgit From 8bf0c256d7f06fe7d0abf031921abd83e6956c8b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 9 Feb 2009 22:22:45 +0100 Subject: s4-smbtorture: add test_AddJob test to RPC-SPOOLSS test. Guenther --- source4/torture/rpc/spoolss.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 04c9768ea8..9d8bc4b186 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -1045,6 +1045,33 @@ static bool test_SetJob(struct torture_context *tctx, return true; } +static bool test_AddJob(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle) +{ + NTSTATUS status; + struct spoolss_AddJob r; + uint32_t needed; + + r.in.level = 0; + r.in.handle = handle; + r.in.offered = 0; + r.out.needed = &needed; + + torture_comment(tctx, "Testing AddJob\n"); + + status = dcerpc_spoolss_AddJob(p, tctx, &r); + torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "AddJob failed"); + + r.in.level = 1; + + status = dcerpc_spoolss_AddJob(p, tctx, &r); + torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM, "AddJob failed"); + + return true; +} + + static bool test_EnumJobs(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) @@ -1084,6 +1111,7 @@ static bool test_EnumJobs(struct torture_context *tctx, info = r.out.info; for (j = 0; j < count; j++) { + test_GetJob(tctx, p, handle, info[j].info1.job_id); test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE); test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME); @@ -1163,6 +1191,7 @@ static bool test_DoPrintTest(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndDocPrinter failed"); torture_assert_werr_ok(tctx, e.out.result, "EndDocPrinter failed"); + ret &= test_AddJob(tctx, p, handle); ret &= test_EnumJobs(tctx, p, handle); ret &= test_SetJob(tctx, p, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE); -- cgit From 7e01ec5560e8193c8e8853ba49c0ee625956c1fd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 23:42:03 +0100 Subject: s4-spoolss: implement dcesrv_spoolss_AddJob which always is a dummy. Guenther --- source4/rpc_server/spoolss/dcesrv_spoolss.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index 89b93bbaa4..f1ef2f0acb 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -546,7 +546,11 @@ static WERROR dcesrv_spoolss_EndDocPrinter(struct dcesrv_call_state *dce_call, T static WERROR dcesrv_spoolss_AddJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct spoolss_AddJob *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + if (r->in.level != 1) { + return WERR_UNKNOWN_LEVEL; + } + + return WERR_INVALID_PARAM; } -- cgit From 9e54f4151cf0e5d958f1929d854d082635b11c39 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 23:43:55 +0100 Subject: s3-spoolss: fix _spoolss_AddJob behaviour. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 2f89775101..5a79dcabc8 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -6619,6 +6619,10 @@ WERROR _spoolss_AddJob(pipes_struct *p, /* this is what a NT server returns for AddJob. AddJob must fail on * non-local printers */ + if (r->in.level != 1) { + return WERR_UNKNOWN_LEVEL; + } + return WERR_INVALID_PARAM; } -- cgit From a6d0a93fc27729b63ae3fd4994059f3854a63845 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2009 14:50:19 -0800 Subject: Use fsp->posix_open in preference if we have it. Jeremy. --- source3/modules/vfs_acl_tdb.c | 10 +++++----- source3/modules/vfs_acl_xattr.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 5cd3e21594..73dbca4809 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -195,7 +195,7 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, if (fsp && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (lp_posix_pathnames()) { + if (fsp->posix_open) { ret = SMB_VFS_LSTAT(handle->conn, name, &sbuf); } else { ret = SMB_VFS_STAT(handle->conn, name, &sbuf); @@ -287,7 +287,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, if (fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (lp_posix_pathnames()) { + if (fsp->posix_open) { ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name, &sbuf); } else { ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf); @@ -513,7 +513,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (lp_posix_pathnames()) { + if (fsp->posix_open) { ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); } else { ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); @@ -763,7 +763,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, return NT_STATUS_OK; } if (fsp->is_directory || fsp->fh->fd == -1) { - if (lp_posix_pathnames()) { + if (fsp->posix_open) { ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); } else { ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); @@ -893,7 +893,7 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); if (fsp->is_directory || fsp->fh->fd == -1) { - if (lp_posix_pathnames()) { + if (fsp->posix_open) { ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); } else { ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index f46e4683aa..039e469426 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -381,7 +381,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (lp_posix_pathnames()) { + if (fsp->posix_open) { ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); } else { ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); @@ -563,7 +563,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, return NT_STATUS_OK; } if (fsp->is_directory || fsp->fh->fd == -1) { - if (lp_posix_pathnames()) { + if (fsp->posix_open) { ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); } else { ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); -- cgit From 59a28a22ab26bb7f2c12f9bccda9c7f585d992a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2009 14:57:16 -0800 Subject: Fix more POSIX path lstat calls. Fix bug where close can return failure if we have a pending modtime and the containing directory of the file has been renamed (there is no POSIX "update time by fd" call). This can't happen on Windows as the rename will fail if there are open files beneath it. Will add a torture test for this. Jeremy. --- source3/smbd/close.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 78b8123680..d23b509af2 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -471,6 +471,7 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) SMB_STRUCT_STAT sbuf; struct smb_file_time ft; NTSTATUS status; + int ret = -1; ZERO_STRUCT(sbuf); ZERO_STRUCT(ft); @@ -485,15 +486,19 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) /* Ensure we have a valid stat struct for the source. */ if (fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf) == -1) { - return map_nt_error_from_unix(errno); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name,&sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf); } } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + if (!VALID_STAT(sbuf)) { /* if it doesn't seem to be a real file */ return NT_STATUS_OK; @@ -581,6 +586,13 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, */ saved_status4 = update_write_time_on_close(fsp); + if (NT_STATUS_EQUAL(saved_status4, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + /* Someone renamed the file or a parent directory containing + * this file. We can't do anything about this, we don't have + * an "update timestamp by fd" call in POSIX. Eat the error. */ + + saved_status4 = NT_STATUS_OK; + } if (NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(saved_status1)) { -- cgit From 76a0050e239b1fb9e2135f2e6cea80ed780a0ee0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 26 Feb 2009 13:12:07 +1100 Subject: A simple hack to avoid the segfault in #6138 Thanks to Andrew Kroeger for reporting this. This fix just for the release. A better fix will make it into the master branch soon. Andrew Bartlett --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index f1c063ed90..2efddc74fc 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1220,7 +1220,7 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA /* Win7-beta will send the domain name in the form the user typed, so we have to cope with both the short and long form here */ - if (strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) { + if (r->in.domain_name == NULL || strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) { r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); } -- cgit From c3632e4efc506a401a9d75c4d75b14a1a220caa2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 26 Feb 2009 13:21:08 +1100 Subject: Mark as the Samba 4.0 alpha7 release --- source4/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/VERSION b/source4/VERSION index e7d05f6a09..20256436eb 100644 --- a/source4/VERSION +++ b/source4/VERSION @@ -89,7 +89,7 @@ SAMBA_VERSION_RC_RELEASE= # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # # -> "3.0.0-SVN-build-199" # ######################################################## -SAMBA_VERSION_IS_GIT_SNAPSHOT=yes +SAMBA_VERSION_IS_GIT_SNAPSHOT=no ######################################################## # This is for specifying a release nickname # -- cgit From b679f6b25673969800f31cf0bd0f57799bb0598c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 09:10:23 +0100 Subject: s4:VERSION: mark as 4.0.0-alpha8 gitsnapshot metze --- source4/VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/VERSION b/source4/VERSION index 20256436eb..58f8cc169d 100644 --- a/source4/VERSION +++ b/source4/VERSION @@ -57,7 +57,7 @@ SAMBA_VERSION_TP_RELEASE= # e.g. SAMBA_VERSION_ALPHA_RELEASE=1 # # -> "4.0.0alpha1" # ######################################################## -SAMBA_VERSION_ALPHA_RELEASE=7 +SAMBA_VERSION_ALPHA_RELEASE=8 ######################################################## # For 'pre' releases the version will be # @@ -89,7 +89,7 @@ SAMBA_VERSION_RC_RELEASE= # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # # -> "3.0.0-SVN-build-199" # ######################################################## -SAMBA_VERSION_IS_GIT_SNAPSHOT=no +SAMBA_VERSION_IS_GIT_SNAPSHOT=yes ######################################################## # This is for specifying a release nickname # -- cgit From 64662cb0c34425f7a0ccc66e43c21b7b69451ca9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 09:42:29 +0100 Subject: s4:ldb_map: include ldb_includes.h first to get replace.h as first header This should bring the build on AIX one step further. metze --- source4/lib/ldb/ldb_map/ldb_map.c | 1 + source4/lib/ldb/ldb_map/ldb_map_inbound.c | 1 + source4/lib/ldb/ldb_map/ldb_map_outbound.c | 1 + 3 files changed, 3 insertions(+) diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c index 959540374c..5b4ea7910a 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.c +++ b/source4/lib/ldb/ldb_map/ldb_map.c @@ -35,6 +35,7 @@ * Author: Jelmer Vernooij, Martin Kuehl */ +#include "ldb_includes.h" #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c index 822dea654e..455740ce59 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c @@ -24,6 +24,7 @@ */ +#include "ldb_includes.h" #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c index eb7b4590ba..ffcefad6be 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c @@ -25,6 +25,7 @@ */ +#include "ldb_includes.h" #include "ldb_map.h" #include "ldb_map_private.h" -- cgit From c21ae8d1bfd4423cf1c4a62c11ba228773548de2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 10:29:55 +0100 Subject: libreplace: make it possible to disable socket_wrapper via -DSOCKET_WRAPPER_DISABLE=1 metze --- lib/replace/system/network.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/replace/system/network.h b/lib/replace/system/network.h index 40d20db2d4..f135d175d4 100644 --- a/lib/replace/system/network.h +++ b/lib/replace/system/network.h @@ -327,10 +327,12 @@ struct addrinfo { #endif #ifdef SOCKET_WRAPPER +#ifndef SOCKET_WRAPPER_DISABLE #ifndef SOCKET_WRAPPER_NOT_REPLACE #define SOCKET_WRAPPER_REPLACE -#endif +#endif /* SOCKET_WRAPPER_NOT_REPLACE */ #include "../socket_wrapper/socket_wrapper.h" -#endif +#endif /* SOCKET_WRAPPER_DISABLE */ +#endif /* SOCKET_WRAPPER */ #endif -- cgit From b6597424dbacdbfcaa37d8860fc4343be1a4514a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 10:05:58 +0100 Subject: s4:heimdal_build: don't always build setprogname.o This hopefully fixes the build on Mac OS 10, where setprogname() is available via libc. asn1_compile and compile_et use only .ho files again and don't use socket_wrapper anymore. metze --- source4/heimdal_build/internal.m4 | 1 + source4/heimdal_build/internal.mk | 50 ++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index a48777fab1..3039c8a796 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -77,6 +77,7 @@ AC_CHECK_FUNCS([ \ atexit \ cgetent \ getprogname \ + setprogname \ inet_aton \ gethostname \ getnameinfo \ diff --git a/source4/heimdal_build/internal.mk b/source4/heimdal_build/internal.mk index 77dbf0fb98..ea8d4731db 100644 --- a/source4/heimdal_build/internal.mk +++ b/source4/heimdal_build/internal.mk @@ -568,27 +568,36 @@ $(heimdalsrcdir)/lib/wind/bidi_table.h $(heimdalsrcdir)/lib/wind/bidi_table.c: $ clean:: @rm -f $(heimdalsrcdir)/lib/wind/bidi_table.h $(heimdalsrcdir)/lib/wind/bidi_table.c -[SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME] +[SUBSYSTEM::HEIMDAL_ROKEN_PROGNAME] -HEIMDAL_ROKEN_GETPROGNAME_OBJ_FILES = $(heimdalsrcdir)/lib/roken/getprogname.o -$(HEIMDAL_ROKEN_GETPROGNAME_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) +HEIMDAL_ROKEN_PROGNAME_OBJ_FILES = \ + $(heimdalsrcdir)/lib/roken/getprogname.o \ + $(heimdalsrcdir)/lib/roken/setprogname.o +$(HEIMDAL_ROKEN_PROGNAME_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) [SUBSYSTEM::HEIMDAL_ROKEN_CLOSEFROM] HEIMDAL_ROKEN_CLOSEFROM_OBJ_FILES = $(heimdalsrcdir)/lib/roken/closefrom.o $(HEIMDAL_ROKEN_CLOSEFROM_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) -[SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME_H] +[SUBSYSTEM::HEIMDAL_ROKEN_PROGNAME_H] -HEIMDAL_ROKEN_GETPROGNAME_H_OBJ_FILES = $(heimdalsrcdir)/lib/roken/getprogname.ho -$(HEIMDAL_ROKEN_GETPROGNAME_H_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) +HEIMDAL_ROKEN_PROGNAME_H_OBJ_FILES = \ + $(heimdalsrcdir)/lib/roken/getprogname.ho \ + $(heimdalsrcdir)/lib/roken/setprogname.ho +$(HEIMDAL_ROKEN_PROGNAME_H_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 + +[SUBSYSTEM::HEIMDAL_ROKEN_CLOSEFROM_H] + +HEIMDAL_ROKEN_CLOSEFROM_H_OBJ_FILES = $(heimdalsrcdir)/lib/roken/closefrom.ho +$(HEIMDAL_ROKEN_CLOSEFROM_H_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 ####################### # Start SUBSYSTEM HEIMDAL_ROKEN [SUBSYSTEM::HEIMDAL_ROKEN] CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) PRIVATE_DEPENDENCIES = \ - HEIMDAL_ROKEN_GETPROGNAME \ + HEIMDAL_ROKEN_PROGNAME \ HEIMDAL_ROKEN_CLOSEFROM \ RESOLV \ LIBREPLACE_NETWORK @@ -615,7 +624,6 @@ HEIMDAL_ROKEN_OBJ_FILES = \ $(heimdalsrcdir)/lib/roken/roken_gethostby.o \ $(heimdalsrcdir)/lib/roken/signal.o \ $(heimdalsrcdir)/lib/roken/vis.o \ - $(heimdalsrcdir)/lib/roken/setprogname.o \ $(heimdalsrcdir)/lib/roken/strlwr.o \ $(heimdalsrcdir)/lib/roken/strsep_copy.o \ $(heimdalsrcdir)/lib/roken/strsep.o \ @@ -631,7 +639,17 @@ HEIMDAL_ROKEN_OBJ_FILES = \ $(heimdalbuildsrcdir)/replace.o $(HEIMDAL_ROKEN_OBJ_FILES) $(HEIMDAL_ROKEN_OBJ_FILES:.o=.d):: $(heimdalsrcdir)/lib/roken/roken.h -$(HEIMDAL_ROKEN_OBJ_FILES:.o=.ho) $(HEIMDAL_ROKEN_OBJ_FILES:.o=.hd):: $(heimdalsrcdir)/lib/roken/roken.h + +[SUBSYSTEM::HEIMDAL_ROKEN_H] +CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 +PRIVATE_DEPENDENCIES = \ + HEIMDAL_ROKEN_PROGNAME_H \ + HEIMDAL_ROKEN_CLOSEFROM_H \ + RESOLV \ + LIBREPLACE_NETWORK + +HEIMDAL_ROKEN_H_OBJ_FILES = $(HEIMDAL_ROKEN_OBJ_FILES:.o=.ho) +$(HEIMDAL_ROKEN_H_OBJ_FILES:.ho=.hd):: $(heimdalsrcdir)/lib/roken/roken.h $(heimdalsrcdir)/lib/roken/roken.h: @echo 'Creating $(heimdalsrcdir)/lib/roken/roken.h' @@ -656,7 +674,7 @@ HEIMDAL_COM_ERR_OBJ_FILES = \ # Start BINARY asn1_compile [BINARY::asn1_compile] USE_HOSTCC = YES -PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN +PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN_H ASN1C = $(builddir)/bin/asn1_compile @@ -680,10 +698,9 @@ dist:: $(heimdalsrcdir)/lib/asn1/lex.c asn1_compile_OBJ_FILES = \ $(asn1_compile_ASN1_OBJ_FILES) \ - $(heimdalsrcdir)/lib/vers/print_version.ho \ - $(socketwrappersrcdir)/socket_wrapper.ho \ + $(heimdalsrcdir)/lib/vers/print_version.ho -$(asn1_compile_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/asn1 -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) +$(asn1_compile_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/asn1 -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 $(eval $(call heimdal_proto_header_template, \ $(heimdalsrcdir)/lib/asn1/der-protos.h, \ @@ -699,7 +716,7 @@ $(eval $(call heimdal_proto_header_template, \ # Start BINARY compile_et [BINARY::compile_et] USE_HOSTCC = YES -PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN +PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN_H # End BINARY compile_et ####################### @@ -708,10 +725,9 @@ ET_COMPILER = $(builddir)/bin/compile_et compile_et_OBJ_FILES = $(heimdalsrcdir)/lib/vers/print_version.ho \ $(heimdalsrcdir)/lib/com_err/parse.ho \ $(heimdalsrcdir)/lib/com_err/lex.ho \ - $(heimdalsrcdir)/lib/com_err/compile_et.ho \ - $(socketwrappersrcdir)/socket_wrapper.ho \ + $(heimdalsrcdir)/lib/com_err/compile_et.ho -$(compile_et_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/com_err -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) +$(compile_et_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/com_err -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 $(heimdalsrcdir)/lib/com_err/lex.c:: $(heimdalsrcdir)/lib/com_err/parse.c dist:: $(heimdalsrcdir)/lib/com_err/lex.c -- cgit From 8e4816f0078fd94a1b83798f52a63dc679eed47e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 10:55:00 +0100 Subject: s4:Makefile: try to fix 'make installheaders' on *BSD systems metze --- source4/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/Makefile b/source4/Makefile index 508836f6da..15b1b8ba40 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -146,7 +146,7 @@ endif clean:: @find ../lib ../libcli ../librpc ../nsswitch -name '*.o' -o -name '*.ho' | xargs rm -f -PUBLIC_HEADERS += $(srcdir)/version.h +PUBLIC_HEADERS += ./version.h libraries:: $(STATIC_LIBS) $(SHARED_LIBS) modules:: $(PLUGINS) -- cgit From 26f238466caa1d40edf74d4678c2e981ec9018bd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Feb 2009 17:01:58 +0100 Subject: Speed up "net conf list" With 1000 shares in the registry, this changed the time of "net conf list" from 1.1 seconds to .6 seconds. Signed-off-by: Michael Adam --- lib/smbconf/smbconf.c | 4 ---- source3/lib/smbconf/smbconf_reg.c | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/smbconf/smbconf.c b/lib/smbconf/smbconf.c index bcab0b97cd..595fd23421 100644 --- a/lib/smbconf/smbconf.c +++ b/lib/smbconf/smbconf.c @@ -203,10 +203,6 @@ WERROR smbconf_get_share(struct smbconf_ctx *ctx, const char *servicename, struct smbconf_service **service) { - if (!smbconf_share_exists(ctx, servicename)) { - return WERR_NO_SUCH_SERVICE; - } - return ctx->ops->get_share(ctx, mem_ctx, servicename, service); } diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index e36fa8a2a1..01de193b3c 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -896,6 +896,9 @@ static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx, werr = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename, REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { + if (W_ERROR_EQUAL(werr, WERR_BADFILE)) { + werr = WERR_NO_SUCH_SERVICE; + } goto done; } -- cgit From 16f61a6f90060d40f0348cb433e3b900ae05fcba Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Feb 2009 18:00:42 +0100 Subject: Speed up "net conf list" For 1000 shares this speeds up net conf list from .6 to .25 seconds on my box Signed-off-by: Michael Adam --- source3/lib/smbconf/smbconf_reg.c | 156 ++++++++++---------------------------- 1 file changed, 41 insertions(+), 115 deletions(-) diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 01de193b3c..b1e34e5164 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -23,7 +23,7 @@ #define INCLUDES_VALNAME "includes" struct reg_private_data { - NT_USER_TOKEN *token; + struct registry_key *base_key; bool open; /* did _we_ open the registry? */ }; @@ -71,54 +71,6 @@ static bool smbconf_reg_valname_valid(const char *valname) lp_parameter_is_valid(valname)); } -/** - * Open a registry key specified by "path" - */ -static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx, - struct smbconf_ctx *ctx, - const char *path, - uint32 desired_access, - struct registry_key **key) -{ - WERROR werr = WERR_OK; - - if (ctx == NULL) { - DEBUG(1, ("Error: configuration is not open!\n")); - werr = WERR_INVALID_PARAM; - goto done; - } - - if (rpd(ctx)->token == NULL) { - DEBUG(1, ("Error: token missing from smbconf_ctx. " - "was smbconf_init() called?\n")); - werr = WERR_INVALID_PARAM; - goto done; - } - - werr = ctx->ops->open_conf(ctx); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, ("Error opening the registry.\n")); - goto done; - } - - if (path == NULL) { - DEBUG(1, ("Error: NULL path string given\n")); - werr = WERR_INVALID_PARAM; - goto done; - } - - werr = reg_open_path(mem_ctx, path, desired_access, rpd(ctx)->token, - key); - - if (!W_ERROR_IS_OK(werr)) { - DEBUG(5, ("Error opening registry path '%s': %s\n", - path, win_errstr(werr))); - } - -done: - return werr; -} - /** * Open a subkey of the base key (i.e a service) */ @@ -128,37 +80,12 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, uint32 desired_access, struct registry_key **key) { - WERROR werr = WERR_OK; - char *path = NULL; - if (servicename == NULL) { - path = talloc_strdup(mem_ctx, ctx->path); - } else { - path = talloc_asprintf(mem_ctx, "%s\\%s", ctx->path, - servicename); - } - if (path == NULL) { - werr = WERR_NOMEM; - goto done; + *key = rpd(ctx)->base_key; + return WERR_OK; } - - werr = smbconf_reg_open_path(mem_ctx, ctx, path, desired_access, key); - -done: - talloc_free(path); - return werr; -} - -/** - * open the base key - */ -static WERROR smbconf_reg_open_base_key(TALLOC_CTX *mem_ctx, - struct smbconf_ctx *ctx, - uint32 desired_access, - struct registry_key **key) -{ - return smbconf_reg_open_path(mem_ctx, ctx, ctx->path, desired_access, - key); + return reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename, + desired_access, key); } /** @@ -189,7 +116,6 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, struct registry_key **newkey) { WERROR werr = WERR_OK; - struct registry_key *create_parent = NULL; TALLOC_CTX *create_ctx; enum winreg_CreateAction action = REG_ACTION_NONE; @@ -198,13 +124,7 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, * and will be destroyed when leaving this function... */ create_ctx = talloc_stackframe(); - werr = smbconf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE, - &create_parent); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - werr = reg_createkey(mem_ctx, create_parent, subkeyname, + werr = reg_createkey(mem_ctx, rpd(ctx)->base_key, subkeyname, REG_KEY_WRITE, newkey, &action); if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) { DEBUG(10, ("Key '%s' already exists.\n", subkeyname)); @@ -215,7 +135,6 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, subkeyname, win_errstr(werr))); } -done: talloc_free(create_ctx); return werr; } @@ -608,6 +527,7 @@ done: static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) { WERROR werr = WERR_OK; + struct nt_user_token *token; if (path == NULL) { path = KEY_SMBCONF; @@ -620,8 +540,7 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) ctx->data = TALLOC_ZERO_P(ctx, struct reg_private_data); - werr = ntstatus_to_werror(registry_create_admin_token(ctx, - &(rpd(ctx)->token))); + werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token)); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("Error creating admin token\n")); goto done; @@ -633,6 +552,19 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) goto done; } + werr = ctx->ops->open_conf(ctx); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("Error opening the registry.\n")); + goto done; + } + + werr = reg_open_path(ctx, ctx->path, + SEC_RIGHTS_ENUM_SUBKEYS | REG_KEY_WRITE, + token, &rpd(ctx)->base_key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + done: return werr; } @@ -723,6 +655,13 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx) struct registry_key *new_key = NULL; TALLOC_CTX* mem_ctx = talloc_stackframe(); enum winreg_CreateAction action; + struct nt_user_token *token; + + werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token)); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("Error creating admin token\n")); + goto done; + } path = talloc_strdup(mem_ctx, ctx->path); if (path == NULL) { @@ -731,8 +670,8 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx) } p = strrchr(path, '\\'); *p = '\0'; - werr = smbconf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE, - &parent_key); + werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token, + &parent_key); if (!W_ERROR_IS_OK(werr)) { goto done; @@ -765,7 +704,6 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, uint32_t added_count = 0; TALLOC_CTX *tmp_ctx = NULL; WERROR werr = WERR_OK; - struct registry_key *key = NULL; char *subkey_name = NULL; char **tmp_share_names = NULL; @@ -777,13 +715,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, tmp_ctx = talloc_stackframe(); /* if there are values in the base key, return NULL as share name */ - werr = smbconf_reg_open_base_key(tmp_ctx, ctx, - SEC_RIGHTS_ENUM_SUBKEYS, &key); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - if (smbconf_reg_key_has_values(key)) { + if (smbconf_reg_key_has_values(rpd(ctx)->base_key)) { werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, 0, NULL); if (!W_ERROR_IS_OK(werr)) { @@ -803,7 +736,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, } for (count = 0; - werr = reg_enumkey(tmp_ctx, key, count, &subkey_name, NULL), + werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count, + &subkey_name, NULL), W_ERROR_IS_OK(werr); count++) { @@ -865,18 +799,16 @@ static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx, const char *servicename) { WERROR werr; - TALLOC_CTX *mem_ctx = talloc_stackframe(); struct registry_key *key = NULL; if (servicename == NULL) { - werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, - &key); - } else { - werr = smbconf_reg_create_service_key(mem_ctx, ctx, - servicename, &key); + return WERR_OK; } - talloc_free(mem_ctx); + werr = smbconf_reg_create_service_key(talloc_tos(), ctx, + servicename, &key); + + talloc_free(key); return werr; } @@ -937,21 +869,15 @@ static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx, const char *servicename) { WERROR werr = WERR_OK; - struct registry_key *key = NULL; TALLOC_CTX *mem_ctx = talloc_stackframe(); - werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - if (servicename != NULL) { - werr = reg_deletekey_recursive(key, key, servicename); + werr = reg_deletekey_recursive(mem_ctx, rpd(ctx)->base_key, + servicename); } else { - werr = smbconf_reg_delete_values(key); + werr = smbconf_reg_delete_values(rpd(ctx)->base_key); } -done: talloc_free(mem_ctx); return werr; } -- cgit From 9475e88beadd19c245ca4010c398652a85ccfd78 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 00:18:05 +0100 Subject: Add dbwrap->parse_record Signed-off-by: Michael Adam --- source3/include/dbwrap.h | 4 ++++ source3/lib/dbwrap.c | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h index aad4ccd721..16f10cc125 100644 --- a/source3/include/dbwrap.h +++ b/source3/include/dbwrap.h @@ -46,6 +46,10 @@ struct db_context { int (*transaction_start)(struct db_context *db); int (*transaction_commit)(struct db_context *db); int (*transaction_cancel)(struct db_context *db); + int (*parse_record)(struct db_context *db, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data); void *private_data; bool persistent; }; diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c index a57b7c97a5..5e7ce6099f 100644 --- a/source3/lib/dbwrap.c +++ b/source3/lib/dbwrap.c @@ -42,6 +42,29 @@ static int dbwrap_fallback_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, return 0; } +/* + * Fall back using fetch if no genuine parse operation is provided + */ + +static int dbwrap_fallback_parse_record(struct db_context *db, TDB_DATA key, + int (*parser)(TDB_DATA key, + TDB_DATA data, + void *private_data), + void *private_data) +{ + TDB_DATA data; + int res; + + res = db->fetch(db, talloc_tos(), key, &data); + if (res != 0) { + return res; + } + + res = parser(key, data, private_data); + TALLOC_FREE(data.dptr); + return res; +} + /** * open a database */ @@ -101,6 +124,9 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx, if ((result != NULL) && (result->fetch == NULL)) { result->fetch = dbwrap_fallback_fetch; } + if ((result != NULL) && (result->parse_record == NULL)) { + result->parse_record = dbwrap_fallback_parse_record; + } return result; } -- cgit From aeb26fe9118ac8b479b2052a722b21e6404c0f00 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 00:47:54 +0100 Subject: Add db_tdb_parse Signed-off-by: Michael Adam --- source3/lib/dbwrap_tdb.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index b5eb1881d4..c71e073b41 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -176,6 +176,17 @@ static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, return 0; } +static int db_tdb_parse(struct db_context *db, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data) +{ + struct db_tdb_ctx *ctx = talloc_get_type_abort( + db->private_data, struct db_tdb_ctx); + + return tdb_parse_record(ctx->wtdb->tdb, key, parser, private_data); +} + static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag) { struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data, @@ -351,6 +362,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, result->fetch = db_tdb_fetch; result->traverse = db_tdb_traverse; result->traverse_read = db_tdb_traverse_read; + result->parse_record = db_tdb_parse; result->get_seqnum = db_tdb_get_seqnum; result->get_flags = db_tdb_get_flags; result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0); -- cgit From 1b1aac412c1cff1ac969ae07a0fe085b80476c9e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 20 Feb 2009 06:01:16 +0100 Subject: Add sorted subkey cache On my box this gets net conf list for 1000 records down to .1 seconds Signed-off-by: Michael Adam --- source3/include/reg_db.h | 1 + source3/registry/reg_backend_db.c | 193 ++++++++++++++++++++++++++++++++++---- 2 files changed, 175 insertions(+), 19 deletions(-) diff --git a/source3/include/reg_db.h b/source3/include/reg_db.h index 92448ae543..5cafa0a5fb 100644 --- a/source3/include/reg_db.h +++ b/source3/include/reg_db.h @@ -26,5 +26,6 @@ #define REG_VALUE_PREFIX "SAMBA_REGVAL" #define REG_SECDESC_PREFIX "SAMBA_SECDESC" +#define REG_SORTED_SUBKEYS_PREFIX "SAMBA_SORTED_SUBKEYS" #endif /* _REG_DB_H */ diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 8ef83a19a1..f6471d04ee 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -578,6 +578,16 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr) goto done; } + /* + * Delete a sorted subkey cache for regdb_key_exists, will be + * recreated automatically + */ + keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX, + keyname); + if (keyname != NULL) { + dbwrap_delete_bystring(regdb, keyname); + } + done: TALLOC_FREE(ctx); SAFE_FREE(buffer); @@ -871,6 +881,169 @@ done: return ret; } +static int cmp_keynames(const void *p1, const void *p2) +{ + return StrCaseCmp(*((char **)p1), *((char **)p2)); +} + +static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) +{ + char **sorted_subkeys; + REGSUBKEY_CTR *ctr; + bool result = false; + NTSTATUS status; + char *buf; + char *p; + int i, res; + size_t len; + + ctr = talloc(talloc_tos(), REGSUBKEY_CTR); + if (ctr == NULL) { + return false; + } + + res = regdb_fetch_keys(key, ctr); + if (res == -1) { + goto fail; + } + + sorted_subkeys = talloc_array(ctr, char *, ctr->num_subkeys); + if (sorted_subkeys == NULL) { + goto fail; + } + + len = 4 + 4*ctr->num_subkeys; + + for (i = 0; inum_subkeys; i++) { + sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, + ctr->subkeys[i]); + if (sorted_subkeys[i] == NULL) { + goto fail; + } + len += strlen(sorted_subkeys[i])+1; + } + + qsort(sorted_subkeys, ctr->num_subkeys, sizeof(char *), cmp_keynames); + + buf = talloc_array(ctr, char, len); + if (buf == NULL) { + goto fail; + } + p = buf + 4 + 4*ctr->num_subkeys; + + SIVAL(buf, 0, ctr->num_subkeys); + + for (i=0; inum_subkeys; i++) { + ptrdiff_t offset = p - buf; + SIVAL(buf, 4 + 4*i, offset); + strlcpy(p, sorted_subkeys[i], len-offset); + p += strlen(sorted_subkeys[i]) + 1; + } + + status = dbwrap_trans_store_bystring( + regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len), + TDB_REPLACE); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + result = true; + fail: + TALLOC_FREE(ctr); + return result; +} + +struct scan_subkey_state { + char *name; + bool scanned; + bool found; +}; + +static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data, + void *private_data) +{ + struct scan_subkey_state *state = + (struct scan_subkey_state *)private_data; + uint32_t num_subkeys; + uint32_t l, u; + + if (data.dsize < sizeof(uint32_t)) { + return -1; + } + + state->scanned = true; + state->found = false; + + tdb_unpack(data.dptr, data.dsize, "d", &num_subkeys); + + l = 0; + u = num_subkeys; + + while (l < u) { + uint32_t idx = (l+u)/2; + char *s = (char *)data.dptr + IVAL(data.dptr, 4 + 4*idx); + int comparison = strcmp(state->name, s); + + if (comparison < 0) { + u = idx; + } else if (comparison > 0) { + l = idx + 1; + } else { + state->found = true; + return 0; + } + } + return 0; +} + +static bool scan_parent_subkeys(const char *parent, const char *name) +{ + char *path = NULL; + char *key = NULL; + struct scan_subkey_state state = { 0, }; + bool result = false; + int res; + + state.name = NULL; + + path = normalize_reg_path(talloc_tos(), parent); + if (path == NULL) { + goto fail; + } + + key = talloc_asprintf(talloc_tos(), "%s/%s", + REG_SORTED_SUBKEYS_PREFIX, path); + if (key == NULL) { + goto fail; + } + + state.name = talloc_strdup_upper(talloc_tos(), name); + if (state.name == NULL) { + goto fail; + } + state.scanned = false; + + res = regdb->parse_record(regdb, string_term_tdb_data(key), + parent_subkey_scanner, &state); + + if (state.scanned) { + result = state.found; + } else { + if (!create_sorted_subkeys(path, key)) { + goto fail; + } + res = regdb->parse_record(regdb, string_term_tdb_data(key), + parent_subkey_scanner, &state); + if ((res == 0) && (state.scanned)) { + result = state.found; + } + } + + fail: + TALLOC_FREE(path); + TALLOC_FREE(state.name); + return result; +} /** * Check for the existence of a key. @@ -907,26 +1080,8 @@ static bool regdb_key_exists(const char *key) value = regdb_fetch_key_internal(mem_ctx, path); ret = (value.dptr != NULL); } else { - /* get the list of subkeys of the parent key */ - uint32 num_items, len, i; - fstring subkeyname; - *p = '\0'; - p++; - value = regdb_fetch_key_internal(mem_ctx, path); - if (value.dptr == NULL) { - goto done; - } - - len = tdb_unpack(value.dptr, value.dsize, "d", &num_items); - for (i = 0; i < num_items; i++) { - len += tdb_unpack(value.dptr +len, value.dsize -len, - "f", &subkeyname); - if (strequal(subkeyname, p)) { - ret = true; - goto done; - } - } + ret = scan_parent_subkeys(path, p+1); } done: -- cgit From 5c91cdcc47dc22330839113b37d250b472fb0487 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 01:11:51 +0100 Subject: Add a comment describing the sorted subkeys Signed-off-by: Michael Adam --- source3/registry/reg_backend_db.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index f6471d04ee..344bc4124d 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -881,6 +881,29 @@ done: return ret; } +/* + * regdb_key_exists() is a very frequent operation. It can be quite + * time-consuming to fully fetch the parent's subkey list, talloc_strdup all + * subkeys and then compare the keyname linearly to all the parent's subkeys. + * + * The following code tries to make this operation as efficient as possible: + * Per registry key we create a list of subkeys that is very efficient to + * search for existence of a subkey. Its format is: + * + * 4 bytes num_subkeys + * 4*num_subkey bytes offset into the string array + * then follows a sorted list of subkeys in uppercase + * + * This record is created by create_sorted_subkeys() on demand if it does not + * exist. scan_parent_subkeys() uses regdb->parse_record to search the sorted + * list, the parsing code and the binary search can be found in + * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of + * the potentially large subkey record. + * + * The sorted subkey record is deleted in regdb_store_keys_internal and + * recreated on demand. + */ + static int cmp_keynames(const void *p1, const void *p2) { return StrCaseCmp(*((char **)p1), *((char **)p2)); -- cgit From 170830c0089088e7e30a3aa2d0c6d65b01ab83a0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 10:11:29 +0100 Subject: Wrap creating the sorted subkey cache in a transaction Signed-off-by: Michael Adam --- source3/registry/reg_backend_db.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 344bc4124d..689bd1038e 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -920,9 +920,15 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) int i, res; size_t len; + if (regdb->transaction_start(regdb) != 0) { + DEBUG(0, ("create_sorted_subkeys: transaction_start " + "failed\n")); + return false; + } + ctr = talloc(talloc_tos(), REGSUBKEY_CTR); if (ctr == NULL) { - return false; + goto fail; } res = regdb_fetch_keys(key, ctr); @@ -963,15 +969,37 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) p += strlen(sorted_subkeys[i]) + 1; } - status = dbwrap_trans_store_bystring( + status = dbwrap_store_bystring( regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len), TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { - goto fail; + /* + * Don't use a "goto fail;" here, this would commit the broken + * transaction. See below for an explanation. + */ + if (regdb->transaction_cancel(regdb) == -1) { + DEBUG(0, ("create_sorted_subkeys: transaction_cancel " + "failed\n")); + } + TALLOC_FREE(ctr); + return false; } result = true; fail: + /* + * We only get here via the "goto fail" when we did not write anything + * yet. Using transaction_commit even in a failure case is necessary + * because this (disposable) call might be nested in other + * transactions. Doing a cancel here would destroy the possibility of + * a transaction_commit for transactions that we might be wrapped in. + */ + if (regdb->transaction_commit(regdb) == -1) { + DEBUG(0, ("create_sorted_subkeys: transaction_start " + "failed\n")); + goto fail; + } + TALLOC_FREE(ctr); return result; } -- cgit From ba0e944c46b5c5e11c2539e15c9fe099a6c39fd1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 10:44:48 +0100 Subject: s3:registry: provide transaction_start|commit|cancel fns for the registry tdb Michael --- source3/include/proto.h | 3 +++ source3/registry/reg_backend_db.c | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 2d92b0fc90..559d62fec3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5049,6 +5049,9 @@ WERROR init_registry_data(void); WERROR regdb_init(void); WERROR regdb_open( void ); int regdb_close( void ); +WERROR regdb_transaction_start(void); +WERROR regdb_transaction_commit(void); +WERROR regdb_transaction_cancel(void); int regdb_get_seqnum(void); bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr); int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr); diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 689bd1038e..960e884404 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -482,6 +482,24 @@ int regdb_close( void ) return 0; } +WERROR regdb_transaction_start(void) +{ + return (regdb->transaction_start(regdb) == 0) ? + WERR_OK : WERR_REG_IO_FAILURE; +} + +WERROR regdb_transaction_commit(void) +{ + return (regdb->transaction_commit(regdb) == 0) ? + WERR_OK : WERR_REG_IO_FAILURE; +} + +WERROR regdb_transaction_cancel(void) +{ + return (regdb->transaction_cancel(regdb) == 0) ? + WERR_OK : WERR_REG_IO_FAILURE; +} + /*********************************************************************** return the tdb sequence number of the registry tdb. this is an indicator for the content of the registry -- cgit From 9f97674ef759c65b874028b7af01fcc65f8dac23 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 15:40:05 +0100 Subject: s3:registry: wrap deletekey_recursive in one big transaction. This speeds up "net conf drop" with 2000 shares on my box from 4m40s to 1m50s, leaving virtually only cpu load. Michael --- source3/registry/reg_api.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index a5f3935821..4dde493a49 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -1133,18 +1133,54 @@ done: return werr; } +static WERROR reg_deletekey_recursive_trans(TALLOC_CTX *ctx, + struct registry_key *parent, + const char *path, + bool del_key) +{ + WERROR werr; + + werr = regdb_transaction_start(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("reg_deletekey_recursive_trans: " + "error starting transaction: %s\n", + win_errstr(werr))); + return werr; + } + + werr = reg_deletekey_recursive_internal(ctx, parent, path, del_key); + + if (!W_ERROR_IS_OK(werr)) { + werr = regdb_transaction_cancel(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("reg_deletekey_recursive_trans: " + "error cancelling transaction: %s\n", + win_errstr(werr))); + } + } else { + werr = regdb_transaction_commit(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("reg_deletekey_recursive_trans: " + "error committing transaction: %s\n", + win_errstr(werr))); + } + } + + return werr; +} + WERROR reg_deletekey_recursive(TALLOC_CTX *ctx, struct registry_key *parent, const char *path) { - return reg_deletekey_recursive_internal(ctx, parent, path, true); + return reg_deletekey_recursive_trans(ctx, parent, path, true); } WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx, struct registry_key *parent, const char *path) { - return reg_deletekey_recursive_internal(ctx, parent, path, false); + return reg_deletekey_recursive_trans(ctx, parent, path, false); } #if 0 -- cgit From bd121b532cf5a6728b7605072f725cc9c6d47f48 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 10:52:30 +0100 Subject: s3:libsmbconf: add transactions to the libsmbconf api This is useful for wrapping higher level aggregate operations in transactions. The text backend implementations just return WERR_OK, the registry backend implementatoins use the regdb_transaction_start|commit|cancel routines just added. Michael --- lib/smbconf/smbconf.c | 15 +++++++++++++++ lib/smbconf/smbconf.h | 4 ++++ lib/smbconf/smbconf_private.h | 3 +++ lib/smbconf/smbconf_txt.c | 17 +++++++++++++++++ source3/lib/smbconf/smbconf_reg.c | 18 ++++++++++++++++++ 5 files changed, 57 insertions(+) diff --git a/lib/smbconf/smbconf.c b/lib/smbconf/smbconf.c index 595fd23421..f25ccae0d4 100644 --- a/lib/smbconf/smbconf.c +++ b/lib/smbconf/smbconf.c @@ -399,3 +399,18 @@ WERROR smbconf_delete_global_includes(struct smbconf_ctx *ctx) return werr; } + +WERROR smbconf_transaction_start(struct smbconf_ctx *ctx) +{ + return ctx->ops->transaction_start(ctx); +} + +WERROR smbconf_transaction_commit(struct smbconf_ctx *ctx) +{ + return ctx->ops->transaction_commit(ctx); +} + +WERROR smbconf_transaction_cancel(struct smbconf_ctx *ctx) +{ + return ctx->ops->transaction_cancel(ctx); +} diff --git a/lib/smbconf/smbconf.h b/lib/smbconf/smbconf.h index 106fae6431..517302ac88 100644 --- a/lib/smbconf/smbconf.h +++ b/lib/smbconf/smbconf.h @@ -94,4 +94,8 @@ WERROR smbconf_set_global_includes(struct smbconf_ctx *ctx, WERROR smbconf_delete_includes(struct smbconf_ctx *ctx, const char *service); WERROR smbconf_delete_global_includes(struct smbconf_ctx *ctx); +WERROR smbconf_transaction_start(struct smbconf_ctx *ctx); +WERROR smbconf_transaction_commit(struct smbconf_ctx *ctx); +WERROR smbconf_transaction_cancel(struct smbconf_ctx *ctx); + #endif /* _LIBSMBCONF_H_ */ diff --git a/lib/smbconf/smbconf_private.h b/lib/smbconf/smbconf_private.h index c9e44181c6..e6998ad639 100644 --- a/lib/smbconf/smbconf_private.h +++ b/lib/smbconf/smbconf_private.h @@ -68,6 +68,9 @@ struct smbconf_ops { uint32_t num_includes, const char **includes); WERROR (*delete_includes)(struct smbconf_ctx *ctx, const char *service); + WERROR (*transaction_start)(struct smbconf_ctx *ctx); + WERROR (*transaction_commit)(struct smbconf_ctx *ctx); + WERROR (*transaction_cancel)(struct smbconf_ctx *ctx); }; struct smbconf_ctx { diff --git a/lib/smbconf/smbconf_txt.c b/lib/smbconf/smbconf_txt.c index 1df4a9fdb7..501382cc5f 100644 --- a/lib/smbconf/smbconf_txt.c +++ b/lib/smbconf/smbconf_txt.c @@ -612,6 +612,20 @@ static WERROR smbconf_txt_delete_includes(struct smbconf_ctx *ctx, return WERR_NOT_SUPPORTED; } +static WERROR smbconf_txt_transaction_start(struct smbconf_ctx *ctx) +{ + return WERR_OK; +} + +static WERROR smbconf_txt_transaction_commit(struct smbconf_ctx *ctx) +{ + return WERR_OK; +} + +static WERROR smbconf_txt_transaction_cancel(struct smbconf_ctx *ctx) +{ + return WERR_OK; +} static struct smbconf_ops smbconf_ops_txt = { .init = smbconf_txt_init, @@ -633,6 +647,9 @@ static struct smbconf_ops smbconf_ops_txt = { .get_includes = smbconf_txt_get_includes, .set_includes = smbconf_txt_set_includes, .delete_includes = smbconf_txt_delete_includes, + .transaction_start = smbconf_txt_transaction_start, + .transaction_commit = smbconf_txt_transaction_commit, + .transaction_cancel = smbconf_txt_transaction_cancel, }; diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index b1e34e5164..5a5c0ead65 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -1066,6 +1066,21 @@ done: return werr; } +static WERROR smbconf_reg_transaction_start(struct smbconf_ctx *ctx) +{ + return regdb_transaction_start(); +} + +static WERROR smbconf_reg_transaction_commit(struct smbconf_ctx *ctx) +{ + return regdb_transaction_commit(); +} + +static WERROR smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx) +{ + return regdb_transaction_cancel(); +} + struct smbconf_ops smbconf_ops_reg = { .init = smbconf_reg_init, .shutdown = smbconf_reg_shutdown, @@ -1086,6 +1101,9 @@ struct smbconf_ops smbconf_ops_reg = { .get_includes = smbconf_reg_get_includes, .set_includes = smbconf_reg_set_includes, .delete_includes = smbconf_reg_delete_includes, + .transaction_start = smbconf_reg_transaction_start, + .transaction_commit = smbconf_reg_transaction_commit, + .transaction_cancel = smbconf_reg_transaction_cancel, }; -- cgit From 42b8d6b3084e235beb8e4ed4215b5973e769ada3 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 10:54:13 +0100 Subject: s3:net: wrap net conf import into one big transaction This speeds up "net conf import" of a file with 2000 shares from 11 minutest to 1m50s on my box. Michael --- source3/utils/net_conf.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c index 0c2cd24fb2..05b552c00d 100644 --- a/source3/utils/net_conf.c +++ b/source3/utils/net_conf.c @@ -331,6 +331,12 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx, "would import the following configuration:\n\n"); } + werr = smbconf_transaction_start(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error starting transaction: %s\n", win_errstr(werr)); + goto done; + } + if (servicename != NULL) { struct smbconf_service *service = NULL; @@ -338,11 +344,11 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx, servicename, &service); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } werr = import_process_service(c, conf_ctx, service); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } } else { struct smbconf_service **services = NULL; @@ -352,24 +358,39 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx, &num_shares, &services); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } if (!c->opt_testmode) { werr = smbconf_drop(conf_ctx); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } } for (sidx = 0; sidx < num_shares; sidx++) { werr = import_process_service(c, conf_ctx, services[sidx]); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } } } - ret = 0; + werr = smbconf_transaction_commit(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error committing transaction: %s\n", + win_errstr(werr)); + } else { + ret = 0; + } + + goto done; + +cancel: + werr = smbconf_transaction_cancel(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error cancelling transaction: %s\n", + win_errstr(werr)); + } done: TALLOC_FREE(mem_ctx); -- cgit From 4d22554e98134755cea609aa6d888c8e67fc123b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2009 10:48:41 +0100 Subject: Add tevent_ntstatus --- lib/util/tevent_ntstatus.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ lib/util/tevent_ntstatus.h | 32 +++++++++++++++++++++++++++++ source3/Makefile.in | 2 +- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 lib/util/tevent_ntstatus.c create mode 100644 lib/util/tevent_ntstatus.h diff --git a/lib/util/tevent_ntstatus.c b/lib/util/tevent_ntstatus.c new file mode 100644 index 0000000000..1a34e9c749 --- /dev/null +++ b/lib/util/tevent_ntstatus.c @@ -0,0 +1,51 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "tevent_ntstatus.h" +#include "../replace/replace.h" + +bool tevent_req_nterror(struct tevent_req *req, NTSTATUS status) +{ + return tevent_req_error(req, NT_STATUS_V(status)); +} + +bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *status) +{ + enum tevent_req_state state; + uint64_t err; + + if (!tevent_req_is_error(req, &state, &err)) { + return false; + } + switch (state) { + case TEVENT_REQ_TIMED_OUT: + *status = NT_STATUS_IO_TIMEOUT; + break; + case TEVENT_REQ_NO_MEMORY: + *status = NT_STATUS_NO_MEMORY; + break; + case TEVENT_REQ_USER_ERROR: + *status = NT_STATUS(err); + break; + default: + *status = NT_STATUS_INTERNAL_ERROR; + break; + } + return true; +} diff --git a/lib/util/tevent_ntstatus.h b/lib/util/tevent_ntstatus.h new file mode 100644 index 0000000000..84c275fb13 --- /dev/null +++ b/lib/util/tevent_ntstatus.h @@ -0,0 +1,32 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _TEVENT_NTSTATUS_H +#define _TEVENT_NTSTATUS_H + +#include +#include +#include "config.h" +#include "../libcli/util/ntstatus.h" +#include "../tevent/tevent.h" + +bool tevent_req_nterror(struct tevent_req *req, NTSTATUS status); +bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *pstatus); + +#endif diff --git a/source3/Makefile.in b/source3/Makefile.in index 8f1d1a5b77..d957d70edb 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -340,7 +340,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ ../lib/util/params.o ../lib/util/talloc_stack.o \ ../lib/util/genrand.o ../lib/util/util_net.o \ ../lib/util/become_daemon.o ../lib/util/system.o \ - ../lib/util/tevent_unix.o + ../lib/util/tevent_unix.o ../lib/util/tevent_ntstatus.o CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ -- cgit From 408cde8fcaac96b82d1cb4d638d790122900cff0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2009 12:34:14 +0100 Subject: Add tevent_req helpers to includes.h --- source3/include/includes.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/include/includes.h b/source3/include/includes.h index 80d7bfc6cf..523a11e255 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -577,6 +577,8 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "../talloc/talloc.h" #include "event.h" +#include "../lib/util/tevent_unix.h" +#include "../lib/util/tevent_ntstatus.h" #include "../lib/util/data_blob.h" #include "../lib/util/time.h" -- cgit From a777b4d50136dc52b69756fdfd6d7024270fe040 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2009 12:34:39 +0100 Subject: Convert open_socket_out to tevent_req --- source3/include/proto.h | 12 ++++---- source3/lib/util_sock.c | 82 ++++++++++++++++++++++++------------------------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 559d62fec3..3fb57e44d4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1423,12 +1423,12 @@ int open_socket_in(int type, bool rebind); NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port, int timeout, int *pfd); -struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const struct sockaddr_storage *pss, - uint16_t port, - int timeout); -NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd); +struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const struct sockaddr_storage *pss, + uint16_t port, + int timeout); +NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd); struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct timeval wait_time, diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 83e8a9d355..b33088db61 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -967,20 +967,20 @@ static int open_socket_out_state_destructor(struct open_socket_out_state *s) Create an outgoing socket. timeout is in milliseconds. **************************************************************************/ -struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const struct sockaddr_storage *pss, - uint16_t port, - int timeout) +struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const struct sockaddr_storage *pss, + uint16_t port, + int timeout) { char addr[INET6_ADDRSTRLEN]; - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *result, *subreq; struct open_socket_out_state *state; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct open_socket_out_state)) { + result = tevent_req_create(mem_ctx, &state, + struct open_socket_out_state); + if (result == NULL) { return NULL; } state->ev = ev; @@ -996,7 +996,8 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, } talloc_set_destructor(state, open_socket_out_state_destructor); - if (!async_req_set_timeout(result, ev, timeval_set(0, timeout*1000))) { + if (!tevent_req_set_endtime( + result, ev, timeval_current_ofs(0, timeout*1000))) { goto fail; } @@ -1030,18 +1031,15 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, || !tevent_req_set_endtime( subreq, state->ev, timeval_current_ofs(0, state->wait_nsec))) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } subreq->async.fn = open_socket_out_connected; subreq->async.private_data = result; return result; post_status: - if (!async_post_ntstatus(result, ev, status)) { - goto fail; - } - return result; + tevent_req_nterror(result, status); + return tevent_req_post(result, ev); fail: TALLOC_FREE(result); return NULL; @@ -1049,17 +1047,18 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, static void open_socket_out_connected(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.private_data, struct tevent_req); struct open_socket_out_state *state = talloc_get_type_abort( - req->private_data, struct open_socket_out_state); + req->private_state, struct open_socket_out_state); int ret; int sys_errno; ret = async_connect_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == 0) { - async_req_done(req); + DEBUG(0, ("calling tevent_req_done from open_socket_out_connected\n")); + tevent_req_done(req); return; } @@ -1082,13 +1081,13 @@ static void open_socket_out_connected(struct tevent_req *subreq) subreq = async_connect_send(state, state->ev, state->fd, (struct sockaddr *)&state->ss, state->salen); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } if (!tevent_req_set_endtime( subreq, state->ev, timeval_current_ofs(0, state->wait_nsec))) { - async_req_error(req, ENOMEM); + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } subreq->async.fn = open_socket_out_connected; @@ -1098,23 +1097,23 @@ static void open_socket_out_connected(struct tevent_req *subreq) #ifdef EISCONN if (sys_errno == EISCONN) { - async_req_done(req); + tevent_req_done(req); return; } #endif /* real error */ - async_req_error(req, sys_errno); + tevent_req_nterror(req, map_nt_error_from_unix(sys_errno)); } -NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd) +NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd) { struct open_socket_out_state *state = talloc_get_type_abort( - req->private_data, struct open_socket_out_state); - int err; + req->private_state, struct open_socket_out_state); + NTSTATUS status; - if (async_req_is_errno(req, &err)) { - return map_nt_error_from_unix(err); + if (tevent_req_is_nterror(req, &status)) { + return status; } *pfd = state->fd; state->fd = -1; @@ -1126,7 +1125,7 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port, { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; - struct async_req *req; + struct tevent_req *req; NTSTATUS status = NT_STATUS_NO_MEMORY; ev = event_context_init(frame); @@ -1138,10 +1137,10 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port, if (req == NULL) { goto fail; } - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); + if (!tevent_req_poll(req, ev)) { + status = NT_STATUS_INTERNAL_ERROR; + goto fail; } - status = open_socket_out_recv(req, pfd); fail: TALLOC_FREE(frame); @@ -1157,7 +1156,7 @@ struct open_socket_out_defer_state { }; static void open_socket_out_defer_waited(struct async_req *subreq); -static void open_socket_out_defer_connected(struct async_req *subreq); +static void open_socket_out_defer_connected(struct tevent_req *subreq); struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, struct event_context *ev, @@ -1204,6 +1203,7 @@ static void open_socket_out_defer_waited(struct async_req *subreq) subreq->async.priv, struct async_req); struct open_socket_out_defer_state *state = talloc_get_type_abort( req->private_data, struct open_socket_out_defer_state); + struct tevent_req *subreq2; bool ret; ret = async_wait_recv(subreq); @@ -1213,19 +1213,19 @@ static void open_socket_out_defer_waited(struct async_req *subreq) return; } - subreq = open_socket_out_send(state, state->ev, &state->ss, - state->port, state->timeout); - if (async_req_nomem(subreq, req)) { + subreq2 = open_socket_out_send(state, state->ev, &state->ss, + state->port, state->timeout); + if (async_req_nomem(subreq2, req)) { return; } - subreq->async.fn = open_socket_out_defer_connected; - subreq->async.priv = req; + subreq2->async.fn = open_socket_out_defer_connected; + subreq2->async.private_data = req; } -static void open_socket_out_defer_connected(struct async_req *subreq) +static void open_socket_out_defer_connected(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct open_socket_out_defer_state *state = talloc_get_type_abort( req->private_data, struct open_socket_out_defer_state); NTSTATUS status; -- cgit From d3ac11c64a95c2041dc0002b8cc59d756736d3be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 13:12:54 +0100 Subject: s4:heimdal_build: correrctly switch closefrom() and get/setprogname() replacements on and off metze --- source4/heimdal_build/internal.m4 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index 3039c8a796..4cd7521c37 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -269,16 +269,18 @@ SMB_ENABLE(compile_et, YES) # only add closefrom if needed SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM, NO) +SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM_H, NO) if test t$ac_cv_func_closefrom != tyes; then SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM, YES) + SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM_H, YES) fi # only add getprogname if needed -SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME, NO) -SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME_H, NO) +SMB_ENABLE(HEIMDAL_ROKEN_PROGNAME, NO) +SMB_ENABLE(HEIMDAL_ROKEN_PROGNAME_H, NO) if test t$ac_cv_func_getprogname != tyes; then - SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME, YES) - SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME_H, YES) + SMB_ENABLE(HEIMDAL_ROKEN_PROGNAME, YES) + SMB_ENABLE(HEIMDAL_ROKEN_PROGNAME_H, YES) fi VPATH="$VPATH:\$(HEIMDAL_VPATH)" -- cgit From 3e25d3bb15fd616fdf89fcb10aba27a9a7586e15 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 00:49:02 +0100 Subject: s3-spoolss: remove some unused defines and structs. Guenther --- source3/include/rpc_spoolss.h | 25 ------------------------- source3/rpc_server/srv_spoolss_nt.c | 3 +-- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 1880331590..fd46102b8e 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -141,20 +141,8 @@ /* Notify field types */ -#define NOTIFY_ONE_VALUE 1 /* Notify data is stored in value1 */ -#define NOTIFY_TWO_VALUE 2 /* Notify data is stored in value2 */ -#define NOTIFY_POINTER 3 /* Data is a pointer to a buffer */ -#define NOTIFY_STRING 4 /* Data is a pointer to a buffer w/length */ -#define NOTIFY_SECDESC 5 /* Data is a security descriptor */ - #define PRINTER_NOTIFY_TYPE 0x00 #define JOB_NOTIFY_TYPE 0x01 -#define PRINT_TABLE_END 0xFF - -#define MAX_PRINTER_NOTIFY 26 -#define MAX_JOB_NOTIFY 24 - -#define MAX_NOTIFY_TYPE_FOR_NOW 26 #define PRINTER_NOTIFY_SERVER_NAME 0x00 #define PRINTER_NOTIFY_PRINTER_NAME 0x01 @@ -323,19 +311,6 @@ PRINTER_DEFAULT; /********************************************/ -typedef struct s_header_type -{ - uint32 type; - union - { - uint32 value; - UNISTR string; - } - data; -} -HEADER_TYPE; - - typedef struct spool_q_getprinterdata { POLICY_HND handle; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 5a79dcabc8..c7fd52d47b 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -3486,7 +3486,6 @@ static const struct s_notify_info_data_table notify_info_data_table[] = { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages }, { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed }, { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size }, -{ PRINT_TABLE_END, 0x0, NULL, 0x0, NULL }, }; /******************************************************************* @@ -3519,7 +3518,7 @@ static bool search_notify(enum spoolss_NotifyType type, { int i; - for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) { + for (i = 0; ARRAY_SIZE(notify_info_data_table); i++) { if (notify_info_data_table[i].type == type && notify_info_data_table[i].field == field && notify_info_data_table[i].fn != NULL) { -- cgit From 76ae2022ad239394c9122f65bd35c1523874e6f9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 01:10:37 +0100 Subject: spoolss: add spoolss_JobStatus. Guenther --- librpc/idl/spoolss.idl | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 2aebed5016..f356294d72 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -378,6 +378,27 @@ import "misc.idl", "security.idl", "winreg.idl"; /******************/ /* Function: 0x02 */ + + /* JOB status codes. */ + + const int JOB_STATUS_QUEUED = 0x0000; + + typedef [bitmap32bit] bitmap { + JOB_STATUS_PAUSED = 0x00000001, + JOB_STATUS_ERROR = 0x00000002, + JOB_STATUS_DELETING = 0x00000004, + JOB_STATUS_SPOOLING = 0x00000008, + JOB_STATUS_PRINTING = 0x00000010, + JOB_STATUS_OFFLINE = 0x00000020, + JOB_STATUS_PAPEROUT = 0x00000040, + JOB_STATUS_PRINTED = 0x00000080, + JOB_STATUS_DELETED = 0x00000100, + JOB_STATUS_BLOCKED_DEVQ = 0x00000200, + JOB_STATUS_USER_INTERVENTION = 0x00000400, + JOB_STATUS_RESTART = 0x00000800, + JOB_STATUS_COMPLETE = 0x00001000 + } spoolss_JobStatus; + typedef struct { uint32 job_id; [relative] nstring *printer_name; @@ -386,7 +407,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *document_name; [relative] nstring *data_type; [relative] nstring *text_status; - uint32 status; + spoolss_JobStatus status; uint32 priority; uint32 position; uint32 total_pages; -- cgit From 54b529a44e4b3244f79f0c5ab3dab91925fae0d4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 01:10:58 +0100 Subject: s3-spoolss: job status defines moved to IDL. Guenther --- source3/include/rpc_spoolss.h | 15 --------------- source3/rpc_server/srv_spoolss_nt.c | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index fd46102b8e..a26a315224 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -124,21 +124,6 @@ #define PRINTER_STATUS_OK 0x00000000 -/* JOB status codes. */ - -#define JOB_STATUS_QUEUED 0x0000 -#define JOB_STATUS_PAUSED 0x0001 -#define JOB_STATUS_ERROR 0x0002 -#define JOB_STATUS_DELETING 0x0004 -#define JOB_STATUS_SPOOLING 0x0008 -#define JOB_STATUS_PRINTING 0x0010 -#define JOB_STATUS_OFFLINE 0x0020 -#define JOB_STATUS_PAPEROUT 0x0040 -#define JOB_STATUS_PRINTED 0x0080 -#define JOB_STATUS_DELETED 0x0100 -#define JOB_STATUS_BLOCKED 0x0200 -#define JOB_STATUS_USER_INTERVENTION 0x0400 - /* Notify field types */ #define PRINTER_NOTIFY_TYPE 0x00 diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index c7fd52d47b..7485a42549 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -110,7 +110,7 @@ static int nt_printj_status(int v) case LPQ_DELETED: return JOB_STATUS_DELETED; case LPQ_BLOCKED: - return JOB_STATUS_BLOCKED; + return JOB_STATUS_BLOCKED_DEVQ; case LPQ_USER_INTERVENTION: return JOB_STATUS_USER_INTERVENTION; } -- cgit From 98ca5b04ba1ca0649b3004fa45cab6aaa8d5ec3c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 13:15:47 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 40 +++++++++++++++++++++++++++++++++++++--- librpc/gen_ndr/ndr_spoolss.h | 1 + librpc/gen_ndr/spoolss.h | 16 ++++++++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 5717da92d4..f9d4461255 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -2520,6 +2520,40 @@ _PUBLIC_ void ndr_print_spoolss_DevmodeContainer(struct ndr_print *ndr, const ch ndr->depth--; } +static enum ndr_err_code ndr_push_spoolss_JobStatus(struct ndr_push *ndr, int ndr_flags, uint32_t r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_JobStatus(struct ndr_pull *ndr, int ndr_flags, uint32_t *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_JobStatus(struct ndr_print *ndr, const char *name, uint32_t r) +{ + ndr_print_uint32(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PAUSED", JOB_STATUS_PAUSED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_ERROR", JOB_STATUS_ERROR, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_DELETING", JOB_STATUS_DELETING, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_SPOOLING", JOB_STATUS_SPOOLING, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PRINTING", JOB_STATUS_PRINTING, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_OFFLINE", JOB_STATUS_OFFLINE, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PAPEROUT", JOB_STATUS_PAPEROUT, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_PRINTED", JOB_STATUS_PRINTED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_DELETED", JOB_STATUS_DELETED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_BLOCKED_DEVQ", JOB_STATUS_BLOCKED_DEVQ, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_USER_INTERVENTION", JOB_STATUS_USER_INTERVENTION, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_RESTART", JOB_STATUS_RESTART, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "JOB_STATUS_COMPLETE", JOB_STATUS_COMPLETE, r); + ndr->depth--; +} + static enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo1 *r) { if (ndr_flags & NDR_SCALARS) { @@ -2561,7 +2595,7 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr NDR_CHECK(ndr_push_relative_ptr1(ndr, r->text_status)); ndr->flags = _flags_save_string; } - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->status)); + NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->status)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->priority)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->total_pages)); @@ -2716,7 +2750,7 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr } ndr->flags = _flags_save_string; } - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->status)); + NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages)); @@ -2859,7 +2893,7 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo1(struct ndr_print *ndr, const char *name ndr_print_string(ndr, "text_status", r->text_status); } ndr->depth--; - ndr_print_uint32(ndr, "status", r->status); + ndr_print_spoolss_JobStatus(ndr, "status", r->status); ndr_print_uint32(ndr, "priority", r->priority); ndr_print_uint32(ndr, "position", r->position); ndr_print_uint32(ndr, "total_pages", r->total_pages); diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index 2e877542a4..bf144229d8 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -235,6 +235,7 @@ enum ndr_err_code ndr_push_spoolss_PrinterInfo(struct ndr_push *ndr, int ndr_fla enum ndr_err_code ndr_pull_spoolss_PrinterInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_PrinterInfo *r); void ndr_print_spoolss_PrinterInfo(struct ndr_print *ndr, const char *name, const union spoolss_PrinterInfo *r); void ndr_print_spoolss_DevmodeContainer(struct ndr_print *ndr, const char *name, const struct spoolss_DevmodeContainer *r); +void ndr_print_spoolss_JobStatus(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_spoolss_JobInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo1 *r); enum ndr_err_code ndr_push_spoolss_JobInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_JobInfo *r); enum ndr_err_code ndr_pull_spoolss_JobInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_JobInfo *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index e758153ca9..25162a0f9c 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -11,6 +11,7 @@ #define _HEADER_spoolss #define PRINTER_ENUM_ICONMASK ( (PRINTER_ENUM_ICON1|PRINTER_ENUM_ICON2|PRINTER_ENUM_ICON3|PRINTER_ENUM_ICON4|PRINTER_ENUM_ICON5|PRINTER_ENUM_ICON6|PRINTER_ENUM_ICON7|PRINTER_ENUM_ICON8) ) +#define JOB_STATUS_QUEUED ( 0x0000 ) #define SPOOLSS_ARCHITECTURE_NT_X86 ( "Windows NT x86" ) #define SPOOLSS_DEFAULT_SERVER_PATH ( "C:\\WINDOWS\\system32\\spool" ) #define PRINTER_CHANGE_PRINTER ( 0x000000FF ) @@ -372,6 +373,21 @@ struct spoolss_DevmodeContainer { struct spoolss_DeviceMode *devmode;/* [unique,subcontext_size(_ndr_size),subcontext(4)] */ }; +/* bitmap spoolss_JobStatus */ +#define JOB_STATUS_PAUSED ( 0x00000001 ) +#define JOB_STATUS_ERROR ( 0x00000002 ) +#define JOB_STATUS_DELETING ( 0x00000004 ) +#define JOB_STATUS_SPOOLING ( 0x00000008 ) +#define JOB_STATUS_PRINTING ( 0x00000010 ) +#define JOB_STATUS_OFFLINE ( 0x00000020 ) +#define JOB_STATUS_PAPEROUT ( 0x00000040 ) +#define JOB_STATUS_PRINTED ( 0x00000080 ) +#define JOB_STATUS_DELETED ( 0x00000100 ) +#define JOB_STATUS_BLOCKED_DEVQ ( 0x00000200 ) +#define JOB_STATUS_USER_INTERVENTION ( 0x00000400 ) +#define JOB_STATUS_RESTART ( 0x00000800 ) +#define JOB_STATUS_COMPLETE ( 0x00001000 ) + struct spoolss_JobInfo1 { uint32_t job_id; const char * printer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -- cgit From 44ceff4d01ce1e7bd089c120f79812f48ced0be7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 13:19:24 +0100 Subject: s3-spoolss: fix search_notify(). sorry... Guenther --- source3/rpc_server/srv_spoolss_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 7485a42549..7a580517d3 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -3518,7 +3518,7 @@ static bool search_notify(enum spoolss_NotifyType type, { int i; - for (i = 0; ARRAY_SIZE(notify_info_data_table); i++) { + for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) { if (notify_info_data_table[i].type == type && notify_info_data_table[i].field == field && notify_info_data_table[i].fn != NULL) { -- cgit From 6cdcfa3fc14eb25c0da072aa549d06e0c33d4598 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2009 13:24:59 +0100 Subject: Remove a temporary debug message -- sorry --- source3/lib/util_sock.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b33088db61..6e75a67a85 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1057,7 +1057,6 @@ static void open_socket_out_connected(struct tevent_req *subreq) ret = async_connect_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == 0) { - DEBUG(0, ("calling tevent_req_done from open_socket_out_connected\n")); tevent_req_done(req); return; } -- cgit From b56f449d6b1cdc527dc553cf0fe774b51a272642 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 17:51:09 +0100 Subject: Revert "Fix a O(n^2) algorithm in regdb_fetch_keys()" This reverts commit a13f065bad0f4d21a67e68b743f17f45bf0a4691. This fix is reverted, because the speedup is going to move further down into reg_objects.c. The unsorted list of subkey names is going to be indexed: This O(n^2) search bites us in more places. This re-establishes the abstraction of reg_objects.c. Michael --- source3/registry/reg_backend_db.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 960e884404..02787738fc 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1166,6 +1166,7 @@ done: int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) { + WERROR werr; uint32 num_items; uint8 *buf; uint32 buflen, len; @@ -1196,35 +1197,12 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) buflen = value.dsize; len = tdb_unpack( buf, buflen, "d", &num_items); - /* - * The following code breaks the abstraction that reg_objects.c sets - * up with regsubkey_ctr_addkey(). But if we use that with the current - * data structure of ctr->subkeys being an unsorted array, we end up - * with an O(n^2) algorithm for retrieving keys from the tdb - * file. This is pretty pointless, as we have to trust the data - * structure on disk not to have duplicates anyway. The alternative to - * breaking this abstraction would be to set up a more sophisticated - * data structure in REGSUBKEY_CTR. - * - * This makes "net conf list" for a registry with >1000 shares - * actually usable :-) - */ - - ctr->subkeys = talloc_array(ctr, char *, num_items); - if (ctr->subkeys == NULL) { - DEBUG(5, ("regdb_fetch_keys: could not allocate subkeys\n")); - goto done; - } - ctr->num_subkeys = num_items; - for (i=0; isubkeys[i] = talloc_strdup(ctr->subkeys, subkeyname); - if (ctr->subkeys[i] == NULL) { - DEBUG(5, ("regdb_fetch_keys: could not allocate " - "subkeyname\n")); - TALLOC_FREE(ctr->subkeys); - ctr->num_subkeys = 0; + werr = regsubkey_ctr_addkey(ctr, subkeyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey " + "failed: %s\n", win_errstr(werr))); goto done; } } -- cgit From 58fc61217db68e553119bc49369362672590c19d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 15:19:18 +0100 Subject: s3:registry: replace typedef "REGSUBKEY_CTR" by "struct regsubkey_ctr" This paves the way for hiding the typedef and the implementation from the surface. Michael --- source3/include/proto.h | 22 +++++++++++----------- source3/include/reg_objects.h | 12 ++++++------ source3/include/regfio.h | 2 +- source3/registry/reg_api.c | 16 ++++++++-------- source3/registry/reg_backend_current_version.c | 2 +- source3/registry/reg_backend_db.c | 26 +++++++++++++------------- source3/registry/reg_backend_hkpt_params.c | 2 +- source3/registry/reg_backend_netlogon_params.c | 2 +- source3/registry/reg_backend_perflib.c | 2 +- source3/registry/reg_backend_printing.c | 20 ++++++++++---------- source3/registry/reg_backend_prod_options.c | 2 +- source3/registry/reg_backend_shares.c | 4 ++-- source3/registry/reg_backend_smbconf.c | 4 ++-- source3/registry/reg_backend_tcpip_params.c | 2 +- source3/registry/reg_dispatcher.c | 6 +++--- source3/registry/reg_eventlog.c | 12 ++++++------ source3/registry/reg_objects.c | 10 +++++----- source3/registry/regfio.c | 2 +- source3/services/services_db.c | 10 +++++----- source3/utils/net_rpc_registry.c | 6 +++--- source3/utils/profiles.c | 6 +++--- 21 files changed, 85 insertions(+), 85 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 3fb57e44d4..8947e762e7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5053,11 +5053,11 @@ WERROR regdb_transaction_start(void); WERROR regdb_transaction_commit(void); WERROR regdb_transaction_cancel(void); int regdb_get_seqnum(void); -bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr); -int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr); +bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr); +int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr); int regdb_fetch_values( const char* key, REGVAL_CTR *values ); bool regdb_store_values( const char *key, REGVAL_CTR *values ); -bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys); +bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys); bool regdb_values_need_update(REGVAL_CTR *values); /* The following definitions come from registry/reg_backend_hkpt_params.c */ @@ -5093,9 +5093,9 @@ void reghook_dump_cache( int debuglevel ); /* The following definitions come from registry/reg_dispatcher.c */ -bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ); +bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys ); bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ); -int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr ); +int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr ); int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ); bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, const struct nt_user_token *token ); @@ -5103,7 +5103,7 @@ WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key, struct security_descriptor **psecdesc); WERROR regkey_set_secdesc(REGISTRY_KEY *key, struct security_descriptor *psecdesc); -bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys); +bool reg_subkeys_need_update(REGISTRY_KEY *key, struct regsubkey_ctr *subkeys); bool reg_values_need_update(REGISTRY_KEY *key, REGVAL_CTR *values); /* The following definitions come from registry/reg_eventlog.c */ @@ -5129,11 +5129,11 @@ WERROR registry_init_smbconf(const char *keyname); /* The following definitions come from registry/reg_objects.c */ -WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ); -int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ); -bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ); -int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ); -char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index ); +WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ); +int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ); +bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ); +int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ); +char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32 key_index ); int regval_ctr_numvals( REGVAL_CTR *ctr ); REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val ); void free_registry_value( REGISTRY_VALUE *val ); diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index d9159dd464..6081eb482c 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -66,11 +66,11 @@ typedef struct { /* container for registry subkey names */ -typedef struct { +struct regsubkey_ctr { uint32 num_subkeys; char **subkeys; int seqnum; -} REGSUBKEY_CTR; +}; /* * @@ -132,9 +132,9 @@ typedef struct { typedef struct { /* functions for enumerating subkeys and values */ - int (*fetch_subkeys)( const char *key, REGSUBKEY_CTR *subkeys); + int (*fetch_subkeys)( const char *key, struct regsubkey_ctr *subkeys); int (*fetch_values) ( const char *key, REGVAL_CTR *val ); - bool (*store_subkeys)( const char *key, REGSUBKEY_CTR *subkeys ); + bool (*store_subkeys)( const char *key, struct regsubkey_ctr *subkeys ); bool (*store_values)( const char *key, REGVAL_CTR *val ); bool (*reg_access_check)( const char *keyname, uint32 requested, uint32 *granted, @@ -143,7 +143,7 @@ typedef struct { struct security_descriptor **psecdesc); WERROR (*set_secdesc)(const char *key, struct security_descriptor *sec_desc); - bool (*subkeys_need_update)(REGSUBKEY_CTR *subkeys); + bool (*subkeys_need_update)(struct regsubkey_ctr *subkeys); bool (*values_need_update)(REGVAL_CTR *values); } REGISTRY_OPS; @@ -164,7 +164,7 @@ typedef struct _RegistryKey { struct registry_key { REGISTRY_KEY *key; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; REGVAL_CTR *values; struct nt_user_token *token; }; diff --git a/source3/include/regfio.h b/source3/include/regfio.h index 63516a358d..0e957d51e5 100644 --- a/source3/include/regfio.h +++ b/source3/include/regfio.h @@ -214,7 +214,7 @@ int regfio_close( REGF_FILE *r ); REGF_NK_REC* regfio_rootkey( REGF_FILE *file ); REGF_NK_REC* regfio_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk ); REGF_NK_REC* regfio_write_key ( REGF_FILE *file, const char *name, - REGVAL_CTR *values, REGSUBKEY_CTR *subkeys, + REGVAL_CTR *values, struct regsubkey_ctr *subkeys, SEC_DESC *sec_desc, REGF_NK_REC *parent ); diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 4dde493a49..35d8e306e0 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -100,7 +100,7 @@ static WERROR fill_subkey_cache(struct registry_key *key) } } - if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) { + if (!(key->subkeys = TALLOC_ZERO_P(key, struct regsubkey_ctr))) { return WERR_NOMEM; } @@ -127,7 +127,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx, WERROR result = WERR_OK; struct registry_key *regkey; REGISTRY_KEY *key; - REGSUBKEY_CTR *subkeys = NULL; + struct regsubkey_ctr *subkeys = NULL; DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name)); @@ -193,7 +193,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx, /* check if the path really exists; failed is indicated by -1 */ /* if the subkey count failed, bail out */ - if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) { + if ( !(subkeys = TALLOC_ZERO_P( key, struct regsubkey_ctr )) ) { result = WERR_NOMEM; goto done; } @@ -726,7 +726,7 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, REGF_NK_REC *subkey; REGISTRY_KEY registry_key; REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; int i; char *path = NULL; WERROR result = WERR_OK; @@ -748,7 +748,7 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, /* now start parsing the values and subkeys */ - subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); + subkeys = TALLOC_ZERO_P(regfile->mem_ctx, struct regsubkey_ctr); if (subkeys == NULL) { return WERR_NOMEM; } @@ -767,7 +767,7 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, (key->values[i].data_size & ~VK_DATA_IN_OFFSET)); } - /* copy subkeys into the REGSUBKEY_CTR */ + /* copy subkeys into the struct regsubkey_ctr */ key->subkey_index = 0; while ((subkey = regfio_fetch_subkey( regfile, key ))) { @@ -861,7 +861,7 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, { REGF_NK_REC *key; REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; int i, num_subkeys; char *key_tmp = NULL; char *keyname, *parentpath; @@ -909,7 +909,7 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, /* lookup the values and subkeys */ - subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); + subkeys = TALLOC_ZERO_P(regfile->mem_ctx, struct regsubkey_ctr); if (subkeys == NULL) { return WERR_NOMEM; } diff --git a/source3/registry/reg_backend_current_version.c b/source3/registry/reg_backend_current_version.c index 04cc0ebfa7..f76840ee22 100644 --- a/source3/registry/reg_backend_current_version.c +++ b/source3/registry/reg_backend_current_version.c @@ -70,7 +70,7 @@ static int current_version_fetch_values(const char *key, REGVAL_CTR *values) } static int current_version_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 02787738fc..5722240f24 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -103,7 +103,7 @@ static WERROR init_registry_key_internal(const char *add_path) char *remaining = NULL; char *keyname; char *subkeyname; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; const char *p, *p2; DEBUG(6, ("init_registry_key: Adding [%s]\n", add_path)); @@ -167,7 +167,7 @@ static WERROR init_registry_key_internal(const char *add_path) * since we are about to update the record. * We just want any subkeys already present */ - if (!(subkeys = TALLOC_ZERO_P(frame, REGSUBKEY_CTR))) { + if (!(subkeys = TALLOC_ZERO_P(frame, struct regsubkey_ctr))) { DEBUG(0,("talloc() failure!\n")); werr = WERR_NOMEM; goto fail; @@ -516,7 +516,7 @@ int regdb_get_seqnum(void) fstrings ***********************************************************************/ -static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr) +static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr) { TDB_DATA dbuf; uint8 *buffer = NULL; @@ -617,11 +617,11 @@ done: do not currently exist ***********************************************************************/ -bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) +bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) { int num_subkeys, i; char *path = NULL; - REGSUBKEY_CTR *subkeys = NULL, *old_subkeys = NULL; + struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL; char *oldkeyname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); NTSTATUS status; @@ -635,7 +635,7 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) * changed */ - if (!(old_subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { + if (!(old_subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr))) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); return false; } @@ -672,7 +672,7 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) * Re-fetch the old keys inside the transaction */ - if (!(old_subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { + if (!(old_subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr))) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -792,7 +792,7 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) num_subkeys = regsubkey_ctr_numkeys(ctr); if (num_subkeys == 0) { - if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) { + if (!(subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr)) ) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -813,7 +813,7 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) if (!path) { goto cancel; } - if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) { + if (!(subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr)) ) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -930,7 +930,7 @@ static int cmp_keynames(const void *p1, const void *p2) static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) { char **sorted_subkeys; - REGSUBKEY_CTR *ctr; + struct regsubkey_ctr *ctr; bool result = false; NTSTATUS status; char *buf; @@ -944,7 +944,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) return false; } - ctr = talloc(talloc_tos(), REGSUBKEY_CTR); + ctr = talloc(talloc_tos(), struct regsubkey_ctr); if (ctr == NULL) { goto fail; } @@ -1164,7 +1164,7 @@ done: released by the caller. ***********************************************************************/ -int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) +int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) { WERROR werr; uint32 num_items; @@ -1484,7 +1484,7 @@ static WERROR regdb_set_secdesc(const char *key, return err; } -bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys) +bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys) { return (regdb_get_seqnum() != subkeys->seqnum); } diff --git a/source3/registry/reg_backend_hkpt_params.c b/source3/registry/reg_backend_hkpt_params.c index 2ed5e78e1c..c67f7b3ea4 100644 --- a/source3/registry/reg_backend_hkpt_params.c +++ b/source3/registry/reg_backend_hkpt_params.c @@ -59,7 +59,7 @@ static int hkpt_params_fetch_values(const char *key, REGVAL_CTR *regvals) } static int hkpt_params_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index 71f88144c8..17abf038a6 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -46,7 +46,7 @@ static int netlogon_params_fetch_values(const char *key, REGVAL_CTR *regvals) } static int netlogon_params_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_perflib.c b/source3/registry/reg_backend_perflib.c index 999bca2682..e23c87efe8 100644 --- a/source3/registry/reg_backend_perflib.c +++ b/source3/registry/reg_backend_perflib.c @@ -95,7 +95,7 @@ static int perflib_fetch_values(const char *key, REGVAL_CTR *regvals) } static int perflib_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_printing.c b/source3/registry/reg_backend_printing.c index 5c1e6eb543..192bc78e09 100644 --- a/source3/registry/reg_backend_printing.c +++ b/source3/registry/reg_backend_printing.c @@ -42,8 +42,8 @@ struct reg_dyn_tree { const char *path; /* callbscks for fetch/store operations */ - int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); - bool (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); + int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys ); + bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys ); int (*fetch_values) ( const char *path, REGVAL_CTR *values ); bool (*store_values) ( const char *path, REGVAL_CTR *values ); }; @@ -77,7 +77,7 @@ static const char *dos_basename(const char *path) ********************************************************************* *********************************************************************/ -static int key_forms_fetch_keys(const char *key, REGSUBKEY_CTR *subkeys) +static int key_forms_fetch_keys(const char *key, struct regsubkey_ctr *subkeys) { char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS)); @@ -196,7 +196,7 @@ static char *strip_printers_prefix(const char *key) /********************************************************************* *********************************************************************/ -static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { int n_services = lp_numservices(); int snum; @@ -275,7 +275,7 @@ done: keyname is the sharename and not the printer name. *********************************************************************/ -static bool add_printers_by_registry( REGSUBKEY_CTR *subkeys ) +static bool add_printers_by_registry( struct regsubkey_ctr *subkeys ) { int i, num_keys, snum; char *printername; @@ -310,7 +310,7 @@ static bool add_printers_by_registry( REGSUBKEY_CTR *subkeys ) /********************************************************************** *********************************************************************/ -static bool key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys ) { char *printers_key; char *printername, *printerdatakey; @@ -738,7 +738,7 @@ static bool key_printers_store_values( const char *key, REGVAL_CTR *values ) ********************************************************************* *********************************************************************/ -static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { const char *environments[] = { "Windows 4.0", @@ -1085,7 +1085,7 @@ static int key_driver_fetch_values( const char *key, REGVAL_CTR *values ) ********************************************************************* *********************************************************************/ -static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { int key_len = strlen(key); @@ -1192,7 +1192,7 @@ static int match_registry_path(const char *key) /*********************************************************************** **********************************************************************/ -static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys ) { int i = match_registry_path( key ); @@ -1208,7 +1208,7 @@ static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) /********************************************************************** *********************************************************************/ -static bool regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys ) { int i = match_registry_path( key ); diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c index 7ac5c5b4b9..3e9d32cd97 100644 --- a/source3/registry/reg_backend_prod_options.c +++ b/source3/registry/reg_backend_prod_options.c @@ -59,7 +59,7 @@ static int prod_options_fetch_values(const char *key, REGVAL_CTR *regvals) } static int prod_options_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_shares.c b/source3/registry/reg_backend_shares.c index ee9e5dc5a1..a30ae34b4e 100644 --- a/source3/registry/reg_backend_shares.c +++ b/source3/registry/reg_backend_shares.c @@ -66,7 +66,7 @@ static char* trim_reg_path( const char *path ) Caller is responsible for freeing memory to **subkeys *********************************************************************/ -static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr ) +static int shares_subkey_info( const char *key, struct regsubkey_ctr *subkey_ctr ) { char *path; bool top_level = False; @@ -134,7 +134,7 @@ static int shares_value_info( const char *key, REGVAL_CTR *val ) (for now at least) *********************************************************************/ -static bool shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys ) +static bool shares_store_subkey( const char *key, struct regsubkey_ctr *subkeys ) { return False; } diff --git a/source3/registry/reg_backend_smbconf.c b/source3/registry/reg_backend_smbconf.c index 2e4a5f1c1d..10ee138e0e 100644 --- a/source3/registry/reg_backend_smbconf.c +++ b/source3/registry/reg_backend_smbconf.c @@ -25,12 +25,12 @@ extern REGISTRY_OPS regdb_ops; /* these are the default */ -static int smbconf_fetch_keys( const char *key, REGSUBKEY_CTR *subkey_ctr ) +static int smbconf_fetch_keys( const char *key, struct regsubkey_ctr *subkey_ctr ) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } -static bool smbconf_store_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static bool smbconf_store_keys( const char *key, struct regsubkey_ctr *subkeys ) { return regdb_ops.store_subkeys(key, subkeys); } diff --git a/source3/registry/reg_backend_tcpip_params.c b/source3/registry/reg_backend_tcpip_params.c index db7df5dd8f..a6aa2fc2ea 100644 --- a/source3/registry/reg_backend_tcpip_params.c +++ b/source3/registry/reg_backend_tcpip_params.c @@ -56,7 +56,7 @@ static int tcpip_params_fetch_values(const char *key, REGVAL_CTR *regvals) } static int tcpip_params_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index c160622054..0db9e1b146 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -80,7 +80,7 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd) High level wrapper function for storing registry subkeys ***********************************************************************/ -bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) +bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys ) { if (key->ops && key->ops->store_subkeys) return key->ops->store_subkeys(key->name, subkeys); @@ -105,7 +105,7 @@ bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) Initialize the TALLOC_CTX if necessary ***********************************************************************/ -int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr ) +int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr ) { int result = -1; @@ -216,7 +216,7 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key, * Check whether the in-memory version of the subkyes of a * registry key needs update from disk. */ -bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys) +bool reg_subkeys_need_update(REGISTRY_KEY *key, struct regsubkey_ctr *subkeys) { if (key->ops && key->ops->subkeys_need_update) { diff --git a/source3/registry/reg_eventlog.c b/source3/registry/reg_eventlog.c index 8994acf107..5617f212eb 100644 --- a/source3/registry/reg_eventlog.c +++ b/source3/registry/reg_eventlog.c @@ -35,7 +35,7 @@ bool eventlog_init_keys(void) const char **elogs = lp_eventlog_list(); char *evtlogpath = NULL; char *evtfilepath = NULL; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; REGVAL_CTR *values; uint32 uiMaxSize; uint32 uiRetention; @@ -44,7 +44,7 @@ bool eventlog_init_keys(void) TALLOC_CTX *ctx = talloc_tos(); while (elogs && *elogs) { - if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { + if (!(subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr ) ) ) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -70,7 +70,7 @@ bool eventlog_init_keys(void) DEBUG( 5, ( "Adding key of [%s] to path of [%s]\n", *elogs, evtlogpath ) ); - if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { + if (!(subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr))) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -197,7 +197,7 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, const char **elogs = lp_eventlog_list( ); char **wrklist, **wp; char *evtlogpath = NULL; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; REGVAL_CTR *values; REGISTRY_VALUE *rval; UNISTR2 data; @@ -315,7 +315,7 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, TALLOC_FREE(values); TALLOC_FREE(wrklist); /* */ - if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { + if ( !( subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr ) ) ) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -342,7 +342,7 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, /* now allocate room for the source's subkeys */ - if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { + if ( !( subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr ) ) ) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 47122ccad2..a9a4939034 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -40,7 +40,7 @@ Add a new key to the array **********************************************************************/ -WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) +WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) { char **newkeys; @@ -77,7 +77,7 @@ WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) Delete a key from the array **********************************************************************/ -int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ) +int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) { int i; @@ -107,7 +107,7 @@ int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ) Check for the existance of a key **********************************************************************/ -bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ) +bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ) { int i; @@ -127,7 +127,7 @@ bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ) How many keys does the container hold ? **********************************************************************/ -int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ) +int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ) { return ctr->num_subkeys; } @@ -136,7 +136,7 @@ int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ) Retreive a specific key string **********************************************************************/ -char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index ) +char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32 key_index ) { if ( ! (key_index < ctr->num_subkeys) ) return NULL; diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index 5395f225f1..d002bd72e7 100644 --- a/source3/registry/regfio.c +++ b/source3/registry/regfio.c @@ -1693,7 +1693,7 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 ) *******************************************************************/ REGF_NK_REC* regfio_write_key( REGF_FILE *file, const char *name, - REGVAL_CTR *values, REGSUBKEY_CTR *subkeys, + REGVAL_CTR *values, struct regsubkey_ctr *subkeys, SEC_DESC *sec_desc, REGF_NK_REC *parent ) { REGF_NK_REC *nk; diff --git a/source3/services/services_db.c b/source3/services/services_db.c index ef975cfbc4..2000ca9272 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -332,14 +332,14 @@ static void fill_service_values( const char *name, REGVAL_CTR *values ) /******************************************************************** ********************************************************************/ -static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, +static void add_new_svc_name( REGISTRY_KEY *key_parent, struct regsubkey_ctr *subkeys, const char *name ) { REGISTRY_KEY *key_service = NULL, *key_secdesc = NULL; WERROR wresult; char *path = NULL; REGVAL_CTR *values = NULL; - REGSUBKEY_CTR *svc_subkeys = NULL; + struct regsubkey_ctr *svc_subkeys = NULL; SEC_DESC *sd = NULL; DATA_BLOB sd_blob; NTSTATUS status; @@ -366,7 +366,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* add the 'Security' key */ - if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) { + if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, struct regsubkey_ctr )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); TALLOC_FREE( key_service ); return; @@ -444,7 +444,7 @@ void svcctl_init_keys( void ) { const char **service_list = lp_svcctl_list(); int i; - REGSUBKEY_CTR *subkeys = NULL; + struct regsubkey_ctr *subkeys = NULL; REGISTRY_KEY *key = NULL; WERROR wresult; @@ -461,7 +461,7 @@ void svcctl_init_keys( void ) /* lookup the available subkeys */ - if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) { + if ( !(subkeys = TALLOC_ZERO_P( key, struct regsubkey_ctr )) ) { DEBUG(0,("svcctl_init_keys: talloc() failed!\n")); TALLOC_FREE( key ); return; diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c index 005e3ca556..4fa5a2fa0a 100644 --- a/source3/utils/net_rpc_registry.c +++ b/source3/utils/net_rpc_registry.c @@ -971,11 +971,11 @@ static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, { REGF_NK_REC *key, *subkey; REGVAL_CTR *values = NULL; - REGSUBKEY_CTR *subkeys = NULL; + struct regsubkey_ctr *subkeys = NULL; int i; char *path = NULL; - if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) { + if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, struct regsubkey_ctr )) ) { DEBUG(0,("write_registry_tree: talloc() failed!\n")); return false; } @@ -993,7 +993,7 @@ static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) ); } - /* copy subkeys into the REGSUBKEY_CTR */ + /* copy subkeys into the struct regsubkey_ctr */ while ( (subkey = regfio_fetch_subkey( infile, nk )) ) { regsubkey_ctr_addkey( subkeys, subkey->keyname ); diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c index bbbaaf089f..2c9bc36faf 100644 --- a/source3/utils/profiles.c +++ b/source3/utils/profiles.c @@ -118,7 +118,7 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, REGF_NK_REC *key, *subkey; SEC_DESC *new_sd; REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; int i; char *path; @@ -132,7 +132,7 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname); swap_sid_in_acl( new_sd, &old_sid, &new_sid ); - if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) { + if ( !(subkeys = TALLOC_ZERO_P( NULL, struct regsubkey_ctr )) ) { DEBUG(0,("copy_registry_tree: talloc() failure!\n")); return False; } @@ -150,7 +150,7 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) ); } - /* copy subkeys into the REGSUBKEY_CTR */ + /* copy subkeys into the struct regsubkey_ctr */ while ( (subkey = regfio_fetch_subkey( infile, nk )) ) { regsubkey_ctr_addkey( subkeys, subkey->keyname ); -- cgit From e05b7a8627a085ebd2418bc52152130a97725535 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 17:30:23 +0100 Subject: s3:registry: don't directly access key->subkeys->num_subkeys in reg_api.c Use the reg_objects api instead. Michael --- source3/registry/reg_api.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 35d8e306e0..06796a7fd0 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -308,7 +308,7 @@ WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key, return err; } - if (idx >= key->subkeys->num_subkeys) { + if (idx >= regsubkey_ctr_numkeys(key->subkeys)) { return WERR_NO_MORE_ITEMS; } @@ -406,11 +406,11 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys, } max_len = 0; - for (i=0; isubkeys->num_subkeys; i++) { + for (i=0; i< regsubkey_ctr_numkeys(key->subkeys); i++) { max_len = MAX(max_len, strlen(key->subkeys->subkeys[i])); } - *num_subkeys = key->subkeys->num_subkeys; + *num_subkeys = regsubkey_ctr_numkeys(key->subkeys); *max_subkeylen = max_len; *max_subkeysize = 0; /* Class length? */ @@ -566,7 +566,7 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path) if (!W_ERROR_IS_OK(err = fill_subkey_cache(key))) { goto error; } - if (key->subkeys->num_subkeys > 0) { + if (regsubkey_ctr_numkeys(key->subkeys) > 0) { err = WERR_ACCESS_DENIED; goto error; } @@ -594,7 +594,7 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path) goto error; } - num_subkeys = parent->subkeys->num_subkeys; + num_subkeys = regsubkey_ctr_numkeys(parent->subkeys); if (regsubkey_ctr_delkey(parent->subkeys, name) == num_subkeys) { err = WERR_BADFILE; -- cgit From 62b53507d29b0679647f429c8d969167fe25122f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 17:42:50 +0100 Subject: s3:registry: don't directly access key->subkeys->num_subkeys in reg_backend_db. Use the reg_objects api instead. Michael --- source3/registry/reg_backend_db.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 5722240f24..fd17b44aab 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -619,7 +619,7 @@ done: bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) { - int num_subkeys, i; + int num_subkeys, old_num_subkeys, i; char *path = NULL; struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL; char *oldkeyname = NULL; @@ -642,16 +642,18 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) regdb_fetch_keys(key, old_subkeys); - if ((ctr->num_subkeys && old_subkeys->num_subkeys) && - (ctr->num_subkeys == old_subkeys->num_subkeys)) { + num_subkeys = regsubkey_ctr_numkeys(ctr); + old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); + if ((num_subkeys && old_num_subkeys) && + (num_subkeys == old_num_subkeys)) { - for (i = 0; inum_subkeys; i++) { + for (i = 0; i < num_subkeys; i++) { if (strcmp(ctr->subkeys[i], old_subkeys->subkeys[i]) != 0) { break; } } - if (i == ctr->num_subkeys) { + if (i == num_subkeys) { /* * Nothing changed, no point to even start a tdb * transaction @@ -937,6 +939,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) char *p; int i, res; size_t len; + int num_subkeys; if (regdb->transaction_start(regdb) != 0) { DEBUG(0, ("create_sorted_subkeys: transaction_start " @@ -954,14 +957,15 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) goto fail; } - sorted_subkeys = talloc_array(ctr, char *, ctr->num_subkeys); + num_subkeys = regsubkey_ctr_numkeys(ctr); + sorted_subkeys = talloc_array(ctr, char *, num_subkeys); if (sorted_subkeys == NULL) { goto fail; } - len = 4 + 4*ctr->num_subkeys; + len = 4 + 4*num_subkeys; - for (i = 0; inum_subkeys; i++) { + for (i = 0; i < num_subkeys; i++) { sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, ctr->subkeys[i]); if (sorted_subkeys[i] == NULL) { @@ -970,17 +974,17 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) len += strlen(sorted_subkeys[i])+1; } - qsort(sorted_subkeys, ctr->num_subkeys, sizeof(char *), cmp_keynames); + qsort(sorted_subkeys, num_subkeys, sizeof(char *), cmp_keynames); buf = talloc_array(ctr, char, len); if (buf == NULL) { goto fail; } - p = buf + 4 + 4*ctr->num_subkeys; + p = buf + 4 + 4*num_subkeys; - SIVAL(buf, 0, ctr->num_subkeys); + SIVAL(buf, 0, num_subkeys); - for (i=0; inum_subkeys; i++) { + for (i=0; i < num_subkeys; i++) { ptrdiff_t offset = p - buf; SIVAL(buf, 4 + 4*i, offset); strlcpy(p, sorted_subkeys[i], len-offset); -- cgit From 8c1e4034fe2ac956cec3854586d3d2fcec268697 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 21:12:26 +0100 Subject: s3:registry: don't directly access key->subkeys->subkeys[] in reg_api.c Use the reg_objects accessor regsubkey_ctr_specific_key() instead. Michael --- source3/registry/reg_api.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 06796a7fd0..6e0e342dba 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -312,7 +312,9 @@ WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key, return WERR_NO_MORE_ITEMS; } - if (!(*name = talloc_strdup(mem_ctx, key->subkeys->subkeys[idx]))) { + if (!(*name = talloc_strdup(mem_ctx, + regsubkey_ctr_specific_key(key->subkeys, idx)))) + { return WERR_NOMEM; } @@ -407,7 +409,8 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys, max_len = 0; for (i=0; i< regsubkey_ctr_numkeys(key->subkeys); i++) { - max_len = MAX(max_len, strlen(key->subkeys->subkeys[i])); + max_len = MAX(max_len, + strlen(regsubkey_ctr_specific_key(key->subkeys, i))); } *num_subkeys = regsubkey_ctr_numkeys(key->subkeys); -- cgit From 63b576424db89739f40e45ac4802634d34456ee6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 22:16:40 +0100 Subject: s3:registry: don't directly access key->subkeys->subkeys[] in reg_backend_db.c Use the reg_objects accessor regsubkey_ctr_specific_key() instead. Michael --- source3/registry/reg_backend_db.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index fd17b44aab..29d0018202 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -648,8 +648,10 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) (num_subkeys == old_num_subkeys)) { for (i = 0; i < num_subkeys; i++) { - if (strcmp(ctr->subkeys[i], - old_subkeys->subkeys[i]) != 0) { + if (strcmp(regsubkey_ctr_specific_key(ctr, i), + regsubkey_ctr_specific_key(old_subkeys, i)) + != 0) + { break; } } @@ -967,7 +969,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) for (i = 0; i < num_subkeys; i++) { sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, - ctr->subkeys[i]); + regsubkey_ctr_specific_key(ctr, i)); if (sorted_subkeys[i] == NULL) { goto fail; } -- cgit From 060abd7e38bff8cecf5821e9a9878f18c04a7a1d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 22:41:40 +0100 Subject: s3:registry: fix a comment Michael --- source3/registry/reg_objects.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index a9a4939034..15f9879706 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -26,9 +26,9 @@ /********************************************************************** - Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d - since the methods use the object pointer as the talloc context for - internal private data. + Note that the struct regsubkey_ctr and REGVAL_CTR objects *must* be + talloc()'d since the methods use the object pointer as the talloc + context for internal private data. There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy() pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the -- cgit From 763f41f39c2b3c3488992297bc1c0e1ab785ad07 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 22:43:47 +0100 Subject: s3:registry: add a regsubkey_ctr_init function for allocating a regsubkey_ctr Michael --- source3/include/proto.h | 1 + source3/registry/reg_objects.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 8947e762e7..dd4fa7b4aa 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5129,6 +5129,7 @@ WERROR registry_init_smbconf(const char *keyname); /* The following definitions come from registry/reg_objects.c */ +WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr); WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ); int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ); bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ); diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 15f9879706..10ad41e84b 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -30,12 +30,26 @@ talloc()'d since the methods use the object pointer as the talloc context for internal private data. - There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy() + There is no longer a regval_ctr_intit() and regval_ctr_destroy() pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the object. **********************************************************************/ +WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) +{ + if (ctr == NULL) { + return WERR_INVALID_PARAM; + } + + *ctr = talloc_zero(mem_ctx, struct regsubkey_ctr); + if (*ctr == NULL) { + return WERR_NOMEM; + } + + return WERR_OK; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ -- cgit From 63ed47c9e4c846d52c7a56b137d5059b1700007a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:10:35 +0100 Subject: s3:registry: add regsubkey_ctr_set_seqnum to hide implementation from caller. Michael --- source3/include/proto.h | 1 + source3/registry/reg_objects.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index dd4fa7b4aa..84ab0efbfe 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5130,6 +5130,7 @@ WERROR registry_init_smbconf(const char *keyname); /* The following definitions come from registry/reg_objects.c */ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr); +WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum); WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ); int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ); bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ); diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 10ad41e84b..20bc906cfe 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -50,6 +50,17 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) return WERR_OK; } +WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum) +{ + if (ctr == NULL) { + return WERR_INVALID_PARAM; + } + + ctr->seqnum = seqnum; + + return WERR_OK; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ -- cgit From cd8bfd3a84a02cdaf74813bb7c09dc9a02621aa6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:15:55 +0100 Subject: s3:registry: add regsubkey_ctr_get_seqnum() to hide implementation Michael --- source3/include/proto.h | 1 + source3/registry/reg_objects.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 84ab0efbfe..4d5e2b5a22 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5131,6 +5131,7 @@ WERROR registry_init_smbconf(const char *keyname); WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr); WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum); +int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr); WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ); int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ); bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ); diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 20bc906cfe..f97ca69139 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -61,6 +61,15 @@ WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum) return WERR_OK; } +int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr) +{ + if (ctr == NULL) { + return -1; + } + + return ctr->seqnum; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ -- cgit From ea2b74090dc58d9d6ac9e78746994d0ebce7ca9e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:17:05 +0100 Subject: s3:registry: use regsubkey_ctr_init() in reg_api.c instead of using talloc on struct regsubkey_ctr. Michael --- source3/registry/reg_api.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 6e0e342dba..66296f0ddd 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -94,15 +94,16 @@ static WERROR fill_value_cache(struct registry_key *key) static WERROR fill_subkey_cache(struct registry_key *key) { + WERROR werr; + if (key->subkeys != NULL) { if (!reg_subkeys_need_update(key->key, key->subkeys)) { return WERR_OK; } } - if (!(key->subkeys = TALLOC_ZERO_P(key, struct regsubkey_ctr))) { - return WERR_NOMEM; - } + werr = regsubkey_ctr_init(key, &(key->subkeys)); + W_ERROR_NOT_OK_RETURN(werr); if (fetch_reg_keys(key->key, key->subkeys) == -1) { TALLOC_FREE(key->subkeys); @@ -193,8 +194,8 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx, /* check if the path really exists; failed is indicated by -1 */ /* if the subkey count failed, bail out */ - if ( !(subkeys = TALLOC_ZERO_P( key, struct regsubkey_ctr )) ) { - result = WERR_NOMEM; + result = regsubkey_ctr_init(key, &subkeys); + if (!W_ERROR_IS_OK(result)) { goto done; } @@ -751,10 +752,8 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, /* now start parsing the values and subkeys */ - subkeys = TALLOC_ZERO_P(regfile->mem_ctx, struct regsubkey_ctr); - if (subkeys == NULL) { - return WERR_NOMEM; - } + result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); + W_ERROR_NOT_OK_RETURN(result); values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); if (values == NULL) { @@ -912,10 +911,8 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, /* lookup the values and subkeys */ - subkeys = TALLOC_ZERO_P(regfile->mem_ctx, struct regsubkey_ctr); - if (subkeys == NULL) { - return WERR_NOMEM; - } + result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); + W_ERROR_NOT_OK_RETURN(result); values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); if (values == NULL) { -- cgit From 3c15d053f543132d434fa0249e3eeeccfeaed43b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:18:20 +0100 Subject: s3:registry: use regsubkey_ctr_init() in reg_backend_db.c instead of using talloc directly. Michael --- source3/registry/reg_backend_db.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 29d0018202..57f10f62a9 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -167,9 +167,9 @@ static WERROR init_registry_key_internal(const char *add_path) * since we are about to update the record. * We just want any subkeys already present */ - if (!(subkeys = TALLOC_ZERO_P(frame, struct regsubkey_ctr))) { + werr = regsubkey_ctr_init(frame, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("talloc() failure!\n")); - werr = WERR_NOMEM; goto fail; } @@ -625,6 +625,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) char *oldkeyname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); NTSTATUS status; + WERROR werr; if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { goto fail; @@ -635,7 +636,8 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) * changed */ - if (!(old_subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr))) { + werr = regsubkey_ctr_init(ctx, &old_subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); return false; } @@ -676,7 +678,8 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) * Re-fetch the old keys inside the transaction */ - if (!(old_subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr))) { + werr = regsubkey_ctr_init(ctx, &old_subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -796,7 +799,8 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) num_subkeys = regsubkey_ctr_numkeys(ctr); if (num_subkeys == 0) { - if (!(subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr)) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -817,7 +821,8 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) if (!path) { goto cancel; } - if (!(subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr)) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -942,6 +947,7 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) int i, res; size_t len; int num_subkeys; + WERROR werr; if (regdb->transaction_start(regdb) != 0) { DEBUG(0, ("create_sorted_subkeys: transaction_start " @@ -949,8 +955,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) return false; } - ctr = talloc(talloc_tos(), struct regsubkey_ctr); - if (ctr == NULL) { + werr = regsubkey_ctr_init(talloc_tos(), &ctr); + if (!W_ERROR_IS_OK(werr)) { goto fail; } -- cgit From 8a74b535c88f7f4adb348e8eb2dccdb1d0f1921c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:19:08 +0100 Subject: s3:registry: use regsubkey_ctr_set_seqnum() in reg_backend_db.c Michael --- source3/registry/reg_backend_db.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 57f10f62a9..15037d5965 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1194,7 +1194,10 @@ int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) goto done; } - ctr->seqnum = regdb_get_seqnum(); + werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum()); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } value = regdb_fetch_key_internal(frame, key); -- cgit From 69be6f5c1d11a7beae41d27fa0d429020cbaf363 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:19:35 +0100 Subject: s3:registry: use regsubkey_ctr_get_seqnum() in reg_backend_db.c Michael --- source3/registry/reg_backend_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 15037d5965..667fa02154 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1501,7 +1501,7 @@ static WERROR regdb_set_secdesc(const char *key, bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys) { - return (regdb_get_seqnum() != subkeys->seqnum); + return (regdb_get_seqnum() != regsubkey_ctr_get_seqnum(subkeys)); } bool regdb_values_need_update(REGVAL_CTR *values) -- cgit From b384d0d49d1c3748c03e86f84ad7f1e4a6bc55b2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:23:04 +0100 Subject: s3:services_db: use regsubkey_ctr_init() instead of using talloc directly Michael --- source3/services/services_db.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/services/services_db.c b/source3/services/services_db.c index 2000ca9272..7a4b90c7cf 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -366,7 +366,8 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, struct regsubkey_ctr *su /* add the 'Security' key */ - if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, struct regsubkey_ctr )) ) { + wresult = regsubkey_ctr_init(key_service, &svc_subkeys); + if (!W_ERROR_IS_OK(wresult)) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); TALLOC_FREE( key_service ); return; @@ -461,7 +462,8 @@ void svcctl_init_keys( void ) /* lookup the available subkeys */ - if ( !(subkeys = TALLOC_ZERO_P( key, struct regsubkey_ctr )) ) { + wresult = regsubkey_ctr_init(key, &subkeys); + if (!W_ERROR_IS_OK(wresult)) { DEBUG(0,("svcctl_init_keys: talloc() failed!\n")); TALLOC_FREE( key ); return; -- cgit From 1ce0035abbff4625621c0ef16af3902959cd342f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 23:28:48 +0100 Subject: s3:registry: use regsubkey_ctr_init() in reg_eventlog.c Michael --- source3/registry/reg_eventlog.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source3/registry/reg_eventlog.c b/source3/registry/reg_eventlog.c index 5617f212eb..c02318beac 100644 --- a/source3/registry/reg_eventlog.c +++ b/source3/registry/reg_eventlog.c @@ -42,9 +42,11 @@ bool eventlog_init_keys(void) uint32 uiCategoryCount; UNISTR2 data; TALLOC_CTX *ctx = talloc_tos(); + WERROR werr; while (elogs && *elogs) { - if (!(subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr ) ) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -70,7 +72,8 @@ bool eventlog_init_keys(void) DEBUG( 5, ( "Adding key of [%s] to path of [%s]\n", *elogs, evtlogpath ) ); - if (!(subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr))) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -207,6 +210,7 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, int i; int numsources; TALLOC_CTX *ctx = talloc_tos(); + WERROR werr; if (!elogs) { return False; @@ -315,7 +319,8 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, TALLOC_FREE(values); TALLOC_FREE(wrklist); /* */ - if ( !( subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr ) ) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -342,7 +347,8 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, /* now allocate room for the source's subkeys */ - if ( !( subkeys = TALLOC_ZERO_P(ctx, struct regsubkey_ctr ) ) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } -- cgit From d2fc3abeeac89fac345ef8218685e490b1a470e6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 00:32:21 +0100 Subject: s3:profiles: use regsubkey_ctr_init() instead of using talloc directly. Michael --- source3/utils/profiles.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c index 2c9bc36faf..0ac93dedeb 100644 --- a/source3/utils/profiles.c +++ b/source3/utils/profiles.c @@ -121,6 +121,7 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, struct regsubkey_ctr *subkeys; int i; char *path; + WERROR werr; /* swap out the SIDs in the security descriptor */ @@ -132,7 +133,8 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname); swap_sid_in_acl( new_sd, &old_sid, &new_sid ); - if ( !(subkeys = TALLOC_ZERO_P( NULL, struct regsubkey_ctr )) ) { + werr = regsubkey_ctr_init(NULL, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("copy_registry_tree: talloc() failure!\n")); return False; } -- cgit From 149d94dd8f5513af9f75d568507c880c63b9187e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 00:33:24 +0100 Subject: s3:registry: remove definition of regsubkey_ctr from the surface. All access is now through accessor functions in reg_objects.c This allows for performance tuning under the hood in the next step. Michael --- source3/include/reg_objects.h | 6 +----- source3/registry/reg_objects.c | 6 ++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index 6081eb482c..421db72d29 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -66,11 +66,7 @@ typedef struct { /* container for registry subkey names */ -struct regsubkey_ctr { - uint32 num_subkeys; - char **subkeys; - int seqnum; -}; +struct regsubkey_ctr; /* * diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index f97ca69139..c3d67a01ed 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -24,6 +24,12 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY +struct regsubkey_ctr { + uint32 num_subkeys; + char **subkeys; + int seqnum; +}; + /********************************************************************** Note that the struct regsubkey_ctr and REGVAL_CTR objects *must* be -- cgit From 0b22f8b99c0291f2e45166124358844127fb8edf Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 09:53:16 +0100 Subject: s3:registry: hash the list of subkeys in the regsubkey_ctr This removes many loops over all the arrays (from regsubkey_ctr_key_exists) and thus reduces "net conf drop" from 1m55 to 48seconds and "net conf import" from 1m55 to 58 seconds for 2000 shares on my box. Michael --- source3/include/proto.h | 2 +- source3/registry/reg_api.c | 10 ++-- source3/registry/reg_objects.c | 123 ++++++++++++++++++++++++++++++++++------- 3 files changed, 108 insertions(+), 27 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 4d5e2b5a22..2a99b4af62 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5133,7 +5133,7 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr); WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum); int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr); WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ); -int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ); +WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ); bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ); int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ); char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32 key_index ); diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 66296f0ddd..7185b1a312 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -552,7 +552,6 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path) WERROR err; TALLOC_CTX *mem_ctx; char *name, *end; - int num_subkeys; struct registry_key *tmp_key, *key; if (!(mem_ctx = talloc_init("reg_createkey"))) return WERR_NOMEM; @@ -598,10 +597,8 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path) goto error; } - num_subkeys = regsubkey_ctr_numkeys(parent->subkeys); - - if (regsubkey_ctr_delkey(parent->subkeys, name) == num_subkeys) { - err = WERR_BADFILE; + err = regsubkey_ctr_delkey(parent->subkeys, name); + if (!W_ERROR_IS_OK(err)) { goto error; } @@ -1151,6 +1148,9 @@ static WERROR reg_deletekey_recursive_trans(TALLOC_CTX *ctx, werr = reg_deletekey_recursive_internal(ctx, parent, path, del_key); if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " failed to delete key '%s' from key " + "'%s': %s\n", path, parent->key->name, + win_errstr(werr))); werr = regdb_transaction_cancel(); if (!W_ERROR_IS_OK(werr)) { DEBUG(0, ("reg_deletekey_recursive_trans: " diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index c3d67a01ed..b975ced324 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -25,8 +25,9 @@ #define DBGC_CLASS DBGC_REGISTRY struct regsubkey_ctr { - uint32 num_subkeys; + uint32_t num_subkeys; char **subkeys; + struct db_context *subkeys_hash; int seqnum; }; @@ -53,6 +54,12 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) return WERR_NOMEM; } + (*ctr)->subkeys_hash = db_open_rbt(*ctr); + if ((*ctr)->subkeys_hash == NULL) { + talloc_free(*ctr); + return WERR_NOMEM; + } + return WERR_OK; } @@ -76,6 +83,68 @@ int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr) return ctr->seqnum; } +static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr, + const char *keyname, + uint32 idx) +{ + WERROR werr; + + werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash, + keyname, + make_tdb_data((uint8 *)&idx, + sizeof(idx)), + TDB_REPLACE)); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("error hashing new key '%s' in container: %s\n", + keyname, win_errstr(werr))); + } + + return werr; +} + +static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr, + const char *keyname) +{ + WERROR werr; + + werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash, + keyname)); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("error unhashing key '%s' in container: %s\n", + keyname, win_errstr(werr))); + } + + return werr; +} + +static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr, + const char *keyname, + uint32 *idx) +{ + TDB_DATA data; + + if ((ctr == NULL) || (keyname == NULL)) { + return WERR_INVALID_PARAM; + } + + data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname); + if (data.dptr == NULL) { + return WERR_NOT_FOUND; + } + + if (data.dsize != sizeof(*idx)) { + talloc_free(data.dptr); + return WERR_INVALID_DATATYPE; + } + + if (idx != NULL) { + *idx = *(uint32 *)data.dptr; + } + + talloc_free(data.dptr); + return WERR_OK; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ @@ -83,6 +152,7 @@ int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr) WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) { char **newkeys; + WERROR werr; if ( !keyname ) { return WERR_OK; @@ -108,6 +178,10 @@ WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) */ return WERR_NOMEM; } + + werr = regsubkey_ctr_hash_keyname(ctr, keyname, ctr->num_subkeys); + W_ERROR_NOT_OK_RETURN(werr); + ctr->num_subkeys++; return WERR_OK; @@ -117,30 +191,37 @@ WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) Delete a key from the array **********************************************************************/ -int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) +WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) { - int i; + WERROR werr; + uint32 idx, j; - if ( !keyname ) - return ctr->num_subkeys; + if (keyname == NULL) { + return WERR_INVALID_PARAM; + } /* make sure the keyname is actually already there */ - for ( i=0; inum_subkeys; i++ ) { - if ( strequal( ctr->subkeys[i], keyname ) ) - break; - } + werr = regsubkey_ctr_index_for_keyname(ctr, keyname, &idx); + W_ERROR_NOT_OK_RETURN(werr); - if ( i == ctr->num_subkeys ) - return ctr->num_subkeys; + werr = regsubkey_ctr_unhash_keyname(ctr, keyname); + W_ERROR_NOT_OK_RETURN(werr); /* update if we have any keys left */ ctr->num_subkeys--; - if ( i < ctr->num_subkeys ) - memmove(&ctr->subkeys[i], &ctr->subkeys[i+1], - sizeof(char*) * (ctr->num_subkeys-i)); + if (idx < ctr->num_subkeys) { + memmove(&ctr->subkeys[idx], &ctr->subkeys[idx+1], + sizeof(char *) * (ctr->num_subkeys - idx)); + + /* we have to re-hash rest of the array... :-( */ + for (j = idx; j < ctr->num_subkeys; j++) { + werr = regsubkey_ctr_hash_keyname(ctr, ctr->subkeys[j], j); + W_ERROR_NOT_OK_RETURN(werr); + } + } - return ctr->num_subkeys; + return WERR_OK; } /*********************************************************************** @@ -149,18 +230,18 @@ int regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ) { - int i; + WERROR werr; if (!ctr->subkeys) { return False; } - for ( i=0; inum_subkeys; i++ ) { - if ( strequal( ctr->subkeys[i],keyname ) ) - return True; + werr = regsubkey_ctr_index_for_keyname(ctr, keyname, NULL); + if (!W_ERROR_IS_OK(werr)) { + return false; } - return False; + return true; } /*********************************************************************** @@ -176,7 +257,7 @@ int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ) Retreive a specific key string **********************************************************************/ -char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32 key_index ) +char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32_t key_index ) { if ( ! (key_index < ctr->num_subkeys) ) return NULL; -- cgit From e026d217bf0d7641ec4f53ede8c6f8eda144a489 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 14:49:30 +0100 Subject: s3:net rpc registry: use regsubkey_ctr_init() instead of using talloc directly. Michael --- source3/utils/net_rpc_registry.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c index 4fa5a2fa0a..00c827928e 100644 --- a/source3/utils/net_rpc_registry.c +++ b/source3/utils/net_rpc_registry.c @@ -974,9 +974,12 @@ static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, struct regsubkey_ctr *subkeys = NULL; int i; char *path = NULL; + WERROR werr; - if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, struct regsubkey_ctr )) ) { - DEBUG(0,("write_registry_tree: talloc() failed!\n")); + werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: " + "%s\n", win_errstr(werr))); return false; } -- cgit From 6c197ffa3090b88663b2507006022fcd438de54c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 16:53:05 +0100 Subject: s3: move definition of W_ERROR_NOT_OK_GOTO_DONE down to libcli/util/werror.h Michael --- libcli/util/werror.h | 6 ++++++ source3/libnet/libnet_join.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libcli/util/werror.h b/libcli/util/werror.h index 4b34b14243..950f009f28 100644 --- a/libcli/util/werror.h +++ b/libcli/util/werror.h @@ -60,6 +60,12 @@ typedef uint32_t WERROR; }\ } while (0) +#define W_ERROR_NOT_OK_GOTO_DONE(x) do { \ + if (!W_ERROR_IS_OK(x)) {\ + goto done;\ + }\ +} while (0) + /* these are win32 error codes. There are only a few places where these matter for Samba, primarily in the NT printing code */ #define WERR_OK W_ERROR(0) diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 20f7b97745..117178f376 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -50,12 +50,6 @@ #define LIBNET_UNJOIN_OUT_DUMP_CTX(ctx, r) \ LIBNET_UNJOIN_DUMP_CTX(ctx, r, NDR_OUT) -#define W_ERROR_NOT_OK_GOTO_DONE(x) do { \ - if (!W_ERROR_IS_OK(x)) {\ - goto done;\ - }\ -} while (0) - /**************************************************************** ****************************************************************/ -- cgit From 51795b723eedecbbcb89c822c68ee51151bc6592 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 16:55:28 +0100 Subject: libcli/util/werror.h: add macro W_ERROR_NOT_OK_GOTO(x, y) a goto destination can be specified as a second parameter. Michael --- libcli/util/werror.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libcli/util/werror.h b/libcli/util/werror.h index 950f009f28..15251a44fc 100644 --- a/libcli/util/werror.h +++ b/libcli/util/werror.h @@ -66,6 +66,12 @@ typedef uint32_t WERROR; }\ } while (0) +#define W_ERROR_NOT_OK_GOTO(x, y) do {\ + if (!W_ERROR_IS_OK(x)) {\ + goto y;\ + }\ +} while(0) + /* these are win32 error codes. There are only a few places where these matter for Samba, primarily in the NT printing code */ #define WERR_OK W_ERROR(0) -- cgit From 602bfeb3605767c2d938f547ddebe5693776028c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 21:59:54 +0100 Subject: s3:registry: add a create_subkey method to the backend ops. This is to provide a more atomic means of adding a subkey of a key. Michael --- source3/include/proto.h | 1 + source3/include/reg_objects.h | 1 + source3/registry/reg_dispatcher.c | 9 +++++++++ 3 files changed, 11 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 2a99b4af62..a4187dc2c6 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5095,6 +5095,7 @@ void reghook_dump_cache( int debuglevel ); bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys ); bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ); +WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey); int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr ); int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ); bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index 421db72d29..29cd4c563d 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -131,6 +131,7 @@ typedef struct { int (*fetch_subkeys)( const char *key, struct regsubkey_ctr *subkeys); int (*fetch_values) ( const char *key, REGVAL_CTR *val ); bool (*store_subkeys)( const char *key, struct regsubkey_ctr *subkeys ); + WERROR (*create_subkey)(const char *key, const char *subkey); bool (*store_values)( const char *key, REGVAL_CTR *val ); bool (*reg_access_check)( const char *keyname, uint32 requested, uint32 *granted, diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index 0db9e1b146..555e821bf1 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -100,6 +100,15 @@ bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) return false; } +WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey) +{ + if (key->ops && key->ops->create_subkey) { + return key->ops->create_subkey(key->name, subkey); + } + + return WERR_NOT_SUPPORTED; +} + /*********************************************************************** High level wrapper function for enumerating registry subkeys Initialize the TALLOC_CTX if necessary -- cgit From 20e40d3b7da084a00cd417c63c79d0bc102462b8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 22:04:07 +0100 Subject: s3:registry: implement create_subkey for the db backend. Michael --- source3/registry/reg_backend_db.c | 67 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 667fa02154..bcec16e95e 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -859,6 +859,72 @@ fail: return false; } +static WERROR regdb_create_subkey(const char *key, const char *subkey) +{ + WERROR werr; + struct regsubkey_ctr *subkeys; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + werr = WERR_NOT_FOUND; + goto done; + } + + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + if (regdb_fetch_keys(key, subkeys) < 0) { + werr = WERR_REG_IO_FAILURE; + goto done; + } + + if (regsubkey_ctr_key_exists(subkeys, subkey)) { + werr = WERR_OK; + goto done; + } + + talloc_free(subkeys); + + werr = regdb_transaction_start(); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + if (regdb_fetch_keys(key, subkeys) < 0) { + werr = WERR_REG_IO_FAILURE; + goto cancel; + } + + werr = regsubkey_ctr_addkey(subkeys, subkey); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + if (!regdb_store_keys_internal(key, subkeys)) { + DEBUG(0, (__location__ " failed to store new subkey list for " + "parent key %s\n", key)); + werr = WERR_REG_IO_FAILURE; + goto cancel; + } + + werr = regdb_transaction_commit(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to commit transaction: %s\n", + win_errstr(werr))); + } + + goto done; + +cancel: + werr = regdb_transaction_cancel(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to cancel transaction: %s\n", + win_errstr(werr))); + } + +done: + talloc_free(mem_ctx); + return werr; +} static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) { @@ -1518,6 +1584,7 @@ REGISTRY_OPS regdb_ops = { .fetch_values = regdb_fetch_values, .store_subkeys = regdb_store_keys, .store_values = regdb_store_values, + .create_subkey = regdb_create_subkey, .get_secdesc = regdb_get_secdesc, .set_secdesc = regdb_set_secdesc, .subkeys_need_update = regdb_subkeys_need_update, -- cgit From d73dafb5fe4339611e3e61f5622a6f8c4b81b1c1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 22:04:58 +0100 Subject: s3:registry: implement create_subkey for the smbconf backend by delegating to the db backend Michael --- source3/registry/reg_backend_smbconf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/registry/reg_backend_smbconf.c b/source3/registry/reg_backend_smbconf.c index 10ee138e0e..3beae8b034 100644 --- a/source3/registry/reg_backend_smbconf.c +++ b/source3/registry/reg_backend_smbconf.c @@ -35,6 +35,11 @@ static bool smbconf_store_keys( const char *key, struct regsubkey_ctr *subkeys ) return regdb_ops.store_subkeys(key, subkeys); } +static WERROR smbconf_create_subkey(const char *key, const char *subkey) +{ + return regdb_ops.create_subkey(key, subkey); +} + static int smbconf_fetch_values( const char *key, REGVAL_CTR *val ) { return regdb_ops.fetch_values(key, val); @@ -79,6 +84,7 @@ REGISTRY_OPS smbconf_reg_ops = { .fetch_values = smbconf_fetch_values, .store_subkeys = smbconf_store_keys, .store_values = smbconf_store_values, + .create_subkey = smbconf_create_subkey, .reg_access_check = smbconf_reg_access_check, .get_secdesc = smbconf_get_secdesc, .set_secdesc = smbconf_set_secdesc, -- cgit From 4b444e4ac4ca0a00a01f22f04bcf01e78593c3a9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 22:06:47 +0100 Subject: s3:registry: use create_reg_subkey() in reg_createkey(). Instead of calling store_reg_keys() On my box, importing 2000 shares into an empty smbconf key now takes some 32 seconds. Michael --- source3/registry/reg_api.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 7185b1a312..9f6ed20568 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -524,14 +524,8 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent, err = fill_subkey_cache(create_parent); if (!W_ERROR_IS_OK(err)) goto done; - err = regsubkey_ctr_addkey(create_parent->subkeys, path); - if (!W_ERROR_IS_OK(err)) goto done; - - if (!store_reg_keys(create_parent->key, create_parent->subkeys)) { - TALLOC_FREE(create_parent->subkeys); - err = WERR_REG_IO_FAILURE; - goto done; - } + err = create_reg_subkey(key->key, path); + W_ERROR_NOT_OK_GOTO_DONE(err); /* * Now open the newly created key -- cgit From 741e902888fe6f6b8109b9bb8ccca48554d00670 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 25 Feb 2009 23:13:07 +0100 Subject: s3:registry: streamline reg_deletekey() somewhat. use W_ERROR_... macros and separate assignments from checks Michael --- source3/registry/reg_api.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 9f6ed20568..d84acff7c5 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -544,39 +544,36 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent, WERROR reg_deletekey(struct registry_key *parent, const char *path) { WERROR err; - TALLOC_CTX *mem_ctx; char *name, *end; struct registry_key *tmp_key, *key; + TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!(mem_ctx = talloc_init("reg_createkey"))) return WERR_NOMEM; - - if (!(name = talloc_strdup(mem_ctx, path))) { + name = talloc_strdup(mem_ctx, path); + if (name == NULL) { err = WERR_NOMEM; - goto error; + goto done; } /* check if the key has subkeys */ err = reg_openkey(mem_ctx, parent, name, REG_KEY_READ, &key); - if (!W_ERROR_IS_OK(err)) { - goto error; - } - if (!W_ERROR_IS_OK(err = fill_subkey_cache(key))) { - goto error; - } + W_ERROR_NOT_OK_GOTO_DONE(err); + + err = fill_subkey_cache(key); + W_ERROR_NOT_OK_GOTO_DONE(err); + if (regsubkey_ctr_numkeys(key->subkeys) > 0) { err = WERR_ACCESS_DENIED; - goto error; + goto done; } /* no subkeys - proceed with delete */ - if ((end = strrchr(name, '\\')) != NULL) { + end = strrchr(name, '\\'); + if (end != NULL) { *end = '\0'; err = reg_openkey(mem_ctx, parent, name, SEC_RIGHTS_CREATE_SUBKEY, &tmp_key); - if (!W_ERROR_IS_OK(err)) { - goto error; - } + W_ERROR_NOT_OK_GOTO_DONE(err); parent = tmp_key; name = end+1; @@ -584,29 +581,26 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path) if (name[0] == '\0') { err = WERR_INVALID_PARAM; - goto error; + goto done; } - if (!W_ERROR_IS_OK(err = fill_subkey_cache(parent))) { - goto error; - } + err = fill_subkey_cache(parent); + W_ERROR_NOT_OK_GOTO_DONE(err); err = regsubkey_ctr_delkey(parent->subkeys, name); - if (!W_ERROR_IS_OK(err)) { - goto error; - } + W_ERROR_NOT_OK_GOTO_DONE(err); if (!store_reg_keys(parent->key, parent->subkeys)) { TALLOC_FREE(parent->subkeys); err = WERR_REG_IO_FAILURE; - goto error; + goto done; } regkey_set_secdesc(key->key, NULL); err = WERR_OK; - error: +done: TALLOC_FREE(mem_ctx); return err; } -- cgit From 2fb944bde1b16179b4d7dd9aafa66d18d742b4e4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 01:16:07 +0100 Subject: s3:registry: refactor deletion of value/secdesc/subkey list tdb records out of regdb_store_values(). Michael --- source3/registry/reg_backend_db.c | 116 ++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 43 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index bcec16e95e..ee0e81f680 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -510,6 +510,61 @@ int regdb_get_seqnum(void) return regdb->get_seqnum(regdb); } + +static WERROR regdb_delete_key_with_prefix(const char *keyname, + const char *prefix) +{ + char *path; + WERROR werr = WERR_NOMEM; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + if (keyname == NULL) { + werr = WERR_INVALID_PARAM; + goto done; + } + + if (prefix == NULL) { + path = discard_const_p(char, keyname); + } else { + path = talloc_asprintf(mem_ctx, "%s/%s", prefix, keyname); + if (path == NULL) { + goto done; + } + } + + path = normalize_reg_path(mem_ctx, path); + if (path == NULL) { + goto done; + } + + werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path)); + + /* treat "not" found" as ok */ + if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { + werr = WERR_OK; + } + +done: + talloc_free(mem_ctx); + return werr; +} + + +static WERROR regdb_delete_values(const char *keyname) +{ + return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX); +} + +static WERROR regdb_delete_secdesc(const char *keyname) +{ + return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX); +} + +static WERROR regdb_delete_subkeylist(const char *keyname) +{ + return regdb_delete_key_with_prefix(keyname, NULL); +} + /*********************************************************************** Add subkey strings to the registry tdb under a defined key fmt is the same format as tdb_pack except this function only supports @@ -624,7 +679,6 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL; char *oldkeyname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); - NTSTATUS status; WERROR werr; if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { @@ -721,12 +775,7 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) continue; } - /* (a) Delete the value list for this key */ - - path = talloc_asprintf(ctx, "%s/%s/%s", - REG_VALUE_PREFIX, - key, - oldkeyname ); + path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname); if (!path) { goto cancel; } @@ -734,53 +783,34 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) if (!path) { goto cancel; } - /* Ignore errors here, we might have no values around */ - dbwrap_delete_bystring(regdb, path); - TALLOC_FREE(path); - /* (b) Delete the secdesc for this key */ + /* (a) Delete the value list for this key */ - path = talloc_asprintf(ctx, "%s/%s/%s", - REG_SECDESC_PREFIX, - key, - oldkeyname ); - if (!path) { - goto cancel; - } - path = normalize_reg_path(ctx, path); - if (!path) { + werr = regdb_delete_values(path); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", + REG_VALUE_PREFIX, path, win_errstr(werr))); goto cancel; } - status = dbwrap_delete_bystring(regdb, path); - /* Don't fail if there are no values around. */ - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) - { - DEBUG(1, ("Deleting %s failed: %s\n", path, - nt_errstr(status))); + + /* (b) Delete the secdesc for this key */ + + werr = regdb_delete_secdesc(path); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", + REG_SECDESC_PREFIX, path, win_errstr(werr))); goto cancel; } - TALLOC_FREE(path); /* (c) Delete the list of subkeys of this key */ - path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname); - if (!path) { - goto cancel; - } - path = normalize_reg_path(ctx, path); - if (!path) { - goto cancel; - } - status = dbwrap_delete_bystring(regdb, path); - /* Don't fail if the subkey record was not found. */ - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) - { - DEBUG(1, ("Deleting %s failed: %s\n", path, - nt_errstr(status))); + werr = regdb_delete_subkeylist(path); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s failed: %s\n", + path, win_errstr(werr))); goto cancel; } + TALLOC_FREE(path); } -- cgit From 13ceeeedbc188f4c68f1c733f0d2ffe1f5978b42 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 01:22:03 +0100 Subject: s3:registry: streamline and cleanup regdb_set_secdesc() somewhat. Michael --- source3/registry/reg_backend_db.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index ee0e81f680..8d483063c4 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -1551,7 +1551,6 @@ static WERROR regdb_set_secdesc(const char *key, { TALLOC_CTX *mem_ctx = talloc_stackframe(); char *tdbkey; - NTSTATUS status; WERROR err = WERR_NOMEM; TDB_DATA tdbdata; @@ -1568,27 +1567,18 @@ static WERROR regdb_set_secdesc(const char *key, if (secdesc == NULL) { /* assuming a delete */ - status = dbwrap_trans_delete_bystring(regdb, tdbkey); - if (NT_STATUS_IS_OK(status)) { - err = WERR_OK; - } else { - err = ntstatus_to_werror(status); - } + err = ntstatus_to_werror(dbwrap_trans_delete_bystring(regdb, + tdbkey)); goto done; } err = ntstatus_to_werror(marshall_sec_desc(mem_ctx, secdesc, &tdbdata.dptr, &tdbdata.dsize)); - if (!W_ERROR_IS_OK(err)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(err); - status = dbwrap_trans_store_bystring(regdb, tdbkey, tdbdata, 0); - if (!NT_STATUS_IS_OK(status)) { - err = ntstatus_to_werror(status); - goto done; - } + err = ntstatus_to_werror(dbwrap_trans_store_bystring(regdb, tdbkey, + tdbdata, 0)); done: TALLOC_FREE(mem_ctx); -- cgit From 61bdfd09edbdea38486bbca3c148d224c7d523fc Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 01:43:58 +0100 Subject: s3:registry: refactor deletion of various subkey lists out of regdb_store_keys() Micheal --- source3/registry/reg_backend_db.c | 61 ++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 8d483063c4..852e54f69d 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -565,6 +565,35 @@ static WERROR regdb_delete_subkeylist(const char *keyname) return regdb_delete_key_with_prefix(keyname, NULL); } +static WERROR regdb_delete_key_lists(const char *keyname) +{ + WERROR werr; + + werr = regdb_delete_values(keyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", + REG_VALUE_PREFIX, keyname, win_errstr(werr))); + goto done; + } + + werr = regdb_delete_secdesc(keyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", + REG_SECDESC_PREFIX, keyname, win_errstr(werr))); + goto done; + } + + werr = regdb_delete_subkeylist(keyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s failed: %s\n", + keyname, win_errstr(werr))); + goto done; + } + +done: + return werr; +} + /*********************************************************************** Add subkey strings to the registry tdb under a defined key fmt is the same format as tdb_pack except this function only supports @@ -779,37 +808,9 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) if (!path) { goto cancel; } - path = normalize_reg_path(ctx, path); - if (!path) { - goto cancel; - } - - /* (a) Delete the value list for this key */ - - werr = regdb_delete_values(path); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", - REG_VALUE_PREFIX, path, win_errstr(werr))); - goto cancel; - } - /* (b) Delete the secdesc for this key */ - - werr = regdb_delete_secdesc(path); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", - REG_SECDESC_PREFIX, path, win_errstr(werr))); - goto cancel; - } - - /* (c) Delete the list of subkeys of this key */ - - werr = regdb_delete_subkeylist(path); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, (__location__ " Deleting %s failed: %s\n", - path, win_errstr(werr))); - goto cancel; - } + werr = regdb_delete_key_lists(path); + W_ERROR_NOT_OK_GOTO(werr, cancel); TALLOC_FREE(path); } -- cgit From 97508eefb78598fcf15c07b4c0cb92dbf21c30f7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 02:54:50 +0100 Subject: s3:registry: add a delete_subkey method to the backend ops. This is to provide a more atomic means of deleting a subkey of a key. Michael --- source3/include/proto.h | 1 + source3/include/reg_objects.h | 1 + source3/registry/reg_dispatcher.c | 9 +++++++++ 3 files changed, 11 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index a4187dc2c6..27b4ce9604 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5096,6 +5096,7 @@ void reghook_dump_cache( int debuglevel ); bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys ); bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ); WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey); +WERROR delete_reg_subkey(REGISTRY_KEY *key, const char *subkey); int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr ); int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ); bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index 29cd4c563d..a03ac1bff4 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -132,6 +132,7 @@ typedef struct { int (*fetch_values) ( const char *key, REGVAL_CTR *val ); bool (*store_subkeys)( const char *key, struct regsubkey_ctr *subkeys ); WERROR (*create_subkey)(const char *key, const char *subkey); + WERROR (*delete_subkey)(const char *key, const char *subkey); bool (*store_values)( const char *key, REGVAL_CTR *val ); bool (*reg_access_check)( const char *keyname, uint32 requested, uint32 *granted, diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index 555e821bf1..106d38e9a5 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -109,6 +109,15 @@ WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey) return WERR_NOT_SUPPORTED; } +WERROR delete_reg_subkey(REGISTRY_KEY *key, const char *subkey) +{ + if (key->ops && key->ops->delete_subkey) { + return key->ops->delete_subkey(key->name, subkey); + } + + return WERR_NOT_SUPPORTED; +} + /*********************************************************************** High level wrapper function for enumerating registry subkeys Initialize the TALLOC_CTX if necessary -- cgit From b5fbe06d746f3e5f004b7006812014dfd269c250 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 02:56:00 +0100 Subject: s3:registry: implement delete_subkey in the db backend Michael --- source3/registry/reg_backend_db.c | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 852e54f69d..30f1db9c53 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -957,6 +957,73 @@ done: return werr; } +static WERROR regdb_delete_subkey(const char *key, const char *subkey) +{ + WERROR werr, werr2; + struct regsubkey_ctr *subkeys; + char *path; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + werr = WERR_NOT_FOUND; + goto done; + } + + path = talloc_asprintf(mem_ctx, "%s/%s", key, subkey); + if (path == NULL) { + werr = WERR_NOMEM; + goto done; + } + + if (!regdb_key_exists(path)) { + werr = WERR_OK; + goto done; + } + + werr = regdb_transaction_start(); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regdb_delete_key_lists(path); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + if (regdb_fetch_keys(key, subkeys) < 0) { + werr = WERR_REG_IO_FAILURE; + goto cancel; + } + + werr = regsubkey_ctr_delkey(subkeys, subkey); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + if (!regdb_store_keys_internal(key, subkeys)) { + DEBUG(0, (__location__ " failed to store new subkey_list for " + "parent key %s\n", key)); + werr = WERR_REG_IO_FAILURE; + goto cancel; + } + + werr = regdb_transaction_commit(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to commit transaction: %s\n", + win_errstr(werr))); + } + + goto done; + +cancel: + werr2 = regdb_transaction_cancel(); + if (!W_ERROR_IS_OK(werr2)) { + DEBUG(0, (__location__ " failed to cancel transaction: %s\n", + win_errstr(werr2))); + } + +done: + talloc_free(mem_ctx); + return werr; +} + static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) { char *path = NULL; @@ -1606,6 +1673,7 @@ REGISTRY_OPS regdb_ops = { .store_subkeys = regdb_store_keys, .store_values = regdb_store_values, .create_subkey = regdb_create_subkey, + .delete_subkey = regdb_delete_subkey, .get_secdesc = regdb_get_secdesc, .set_secdesc = regdb_set_secdesc, .subkeys_need_update = regdb_subkeys_need_update, -- cgit From ae8c584218fd25016f9baf3106eb25a2faf15a97 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 02:56:50 +0100 Subject: s3:registry: implement delete_subkey in the smbconf backend delegating the call to the db backend Michael --- source3/registry/reg_backend_smbconf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/registry/reg_backend_smbconf.c b/source3/registry/reg_backend_smbconf.c index 3beae8b034..8e1bbcab6f 100644 --- a/source3/registry/reg_backend_smbconf.c +++ b/source3/registry/reg_backend_smbconf.c @@ -40,6 +40,11 @@ static WERROR smbconf_create_subkey(const char *key, const char *subkey) return regdb_ops.create_subkey(key, subkey); } +static WERROR smbconf_delete_subkey(const char *key, const char *subkey) +{ + return regdb_ops.delete_subkey(key, subkey); +} + static int smbconf_fetch_values( const char *key, REGVAL_CTR *val ) { return regdb_ops.fetch_values(key, val); @@ -85,6 +90,7 @@ REGISTRY_OPS smbconf_reg_ops = { .store_subkeys = smbconf_store_keys, .store_values = smbconf_store_values, .create_subkey = smbconf_create_subkey, + .delete_subkey = smbconf_delete_subkey, .reg_access_check = smbconf_reg_access_check, .get_secdesc = smbconf_get_secdesc, .set_secdesc = smbconf_set_secdesc, -- cgit From 270ab5544b9e2a26e00ccb4e27e24996bf2e9238 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 02:57:59 +0100 Subject: s3:registry: use delete_reg_subkey() in reg_deletekey() This further speeds up net conf drop. Michael --- source3/registry/reg_api.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index d84acff7c5..3dc3bae6fe 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -584,21 +584,7 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path) goto done; } - err = fill_subkey_cache(parent); - W_ERROR_NOT_OK_GOTO_DONE(err); - - err = regsubkey_ctr_delkey(parent->subkeys, name); - W_ERROR_NOT_OK_GOTO_DONE(err); - - if (!store_reg_keys(parent->key, parent->subkeys)) { - TALLOC_FREE(parent->subkeys); - err = WERR_REG_IO_FAILURE; - goto done; - } - - regkey_set_secdesc(key->key, NULL); - - err = WERR_OK; + err = delete_reg_subkey(parent->key, name); done: TALLOC_FREE(mem_ctx); -- cgit From 2f4b8213206aebd7b101b9623f7cd0786a65f310 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 02:59:07 +0100 Subject: s3:registry: tighten the subkey loop in reg_deletekey_recursive() and loop from the end to the beginning so that we don't need to rehash the subkeys... This gets "net conf drop" with 2000 shares down to 14 seconds on my box. Michael --- source3/registry/reg_api.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 3dc3bae6fe..67767a2e56 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -1062,6 +1062,7 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx, WERROR werr = WERR_OK; struct registry_key *key; char *subkey_name = NULL; + uint32 i; mem_ctx = talloc_new(ctx); if (mem_ctx == NULL) { @@ -1075,25 +1076,21 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx, goto done; } - while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0, - &subkey_name, NULL))) - { + werr = fill_subkey_cache(key); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + /* + * loop from top to bottom for perfomance: + * this way, we need to rehash the regsubkey containers less + */ + for (i = regsubkey_ctr_numkeys(key->subkeys) ; i > 0; i--) { + subkey_name = regsubkey_ctr_specific_key(key->subkeys, i-1); werr = reg_deletekey_recursive_internal(mem_ctx, key, - subkey_name, - true); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - } - if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { - DEBUG(1, ("reg_deletekey_recursive_internal: " - "Error enumerating subkeys: %s\n", - win_errstr(werr))); - goto done; + subkey_name, + true); + W_ERROR_NOT_OK_GOTO_DONE(werr); } - werr = WERR_OK; - if (del_key) { /* now delete the actual key */ werr = reg_deletekey(parent, path); -- cgit From 3a1f24f286d4dba836b750122f571f831a794e4a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Feb 2009 11:42:01 +0100 Subject: tevent: add tevent_queue infrastructure metze --- lib/tevent/libtevent.m4 | 2 +- lib/tevent/tevent.h | 22 ++++++ lib/tevent/tevent_queue.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 lib/tevent/tevent_queue.c diff --git a/lib/tevent/libtevent.m4 b/lib/tevent/libtevent.m4 index 29a64ae3b3..c316823a71 100644 --- a/lib/tevent/libtevent.m4 +++ b/lib/tevent/libtevent.m4 @@ -27,7 +27,7 @@ AC_SUBST(TEVENT_LIBS) TEVENT_CFLAGS="-I$teventdir" TEVENT_OBJ="tevent.o tevent_fd.o tevent_timed.o tevent_signal.o tevent_debug.o tevent_util.o" -TEVENT_OBJ="$TEVENT_OBJ tevent_req.o tevent_wakeup.o" +TEVENT_OBJ="$TEVENT_OBJ tevent_req.o tevent_wakeup.o tevent_queue.o" TEVENT_OBJ="$TEVENT_OBJ tevent_standard.o tevent_select.o" AC_CHECK_HEADERS(sys/epoll.h) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 185a8fa193..8c119ffb8e 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -338,6 +338,28 @@ struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs); +struct tevent_queue; + +struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, + const char *name, + const char *location); + +#define tevent_queue_create(_mem_ctx, _name) \ + _tevent_queue_create((_mem_ctx), (_name), __location__) + +typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req, + void *private_data); +bool tevent_queue_add(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data); +bool tevent_queue_start(struct tevent_queue *queue, + struct tevent_context *ev); +void tevent_queue_stop(struct tevent_queue *queue); + +size_t tevent_queue_length(struct tevent_queue *queue); + #ifdef TEVENT_COMPAT_DEFINES #define event_context tevent_context diff --git a/lib/tevent/tevent_queue.c b/lib/tevent/tevent_queue.c new file mode 100644 index 0000000000..6c8fbe4f95 --- /dev/null +++ b/lib/tevent/tevent_queue.c @@ -0,0 +1,198 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async requests + Copyright (C) Volker Lendecke 2008 + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +struct tevent_queue_entry { + struct tevent_queue_entry *prev, *next; + struct tevent_queue *queue; + + bool triggered; + + struct tevent_req *req; + + tevent_queue_trigger_fn_t trigger; + void *private_data; +}; + +struct tevent_queue { + const char *name; + const char *location; + + bool running; + struct tevent_timer *timer; + + size_t length; + struct tevent_queue_entry *list; +}; + +static int tevent_queue_entry_destructor(struct tevent_queue_entry *e) +{ + struct tevent_queue *q = e->queue; + + if (!q) { + return 0; + } + + DLIST_REMOVE(q->list, e); + q->length--; + + if (e->triggered && + q->running && + q->list) { + q->list->triggered = true; + q->list->trigger(q->list->req, + q->list->private_data); + } + + return 0; +} + +static int tevent_queue_destructor(struct tevent_queue *q) +{ + q->running = false; + + while (q->list) { + struct tevent_queue_entry *e = q->list; + talloc_free(e); + } + + return 0; +} + +struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, + const char *name, + const char *location) +{ + struct tevent_queue *queue; + + queue = talloc_zero(mem_ctx, struct tevent_queue); + if (!queue) { + return NULL; + } + + queue->name = talloc_strdup(queue, name); + if (!queue->name) { + talloc_free(queue); + return NULL; + } + + queue->location = location; + + /* queue is running by default */ + queue->running = true; + + talloc_set_destructor(queue, tevent_queue_destructor); + return queue; +} + +static void tevent_queue_timer_start(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval now, + void *private_data) +{ + struct tevent_queue *q = talloc_get_type(private_data, + struct tevent_queue); + + talloc_free(te); + q->timer = NULL; + + q->list->triggered = true; + q->list->trigger(q->list->req, q->list->private_data); +} + +bool tevent_queue_add(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +{ + struct tevent_queue_entry *e; + + e = talloc_zero(req, struct tevent_queue_entry); + if (e == NULL) { + return false; + } + + e->queue = queue; + e->req = req; + e->trigger = trigger; + e->private_data = private_data; + + if (queue->running && + !queue->timer && + !queue->list) { + queue->timer = tevent_add_timer(ev, queue, tevent_timeval_zero(), + tevent_queue_timer_start, + queue); + if (!queue->timer) { + talloc_free(e); + return false; + } + } + + DLIST_ADD_END(queue->list, e, struct tevent_queue_entry *); + queue->length++; + talloc_set_destructor(e, tevent_queue_entry_destructor); + + return true; +} + +bool tevent_queue_start(struct tevent_queue *queue, + struct tevent_context *ev) +{ + if (queue->running) { + /* already started */ + return true; + } + + if (!queue->timer && + queue->list) { + queue->timer = tevent_add_timer(ev, queue, tevent_timeval_zero(), + tevent_queue_timer_start, + queue); + if (!queue->timer) { + return false; + } + } + + queue->running = true; + + return true; +} + +void tevent_queue_stop(struct tevent_queue *queue) +{ + queue->running = false; + talloc_free(queue->timer); + queue->timer = NULL; +} + +size_t tevent_queue_length(struct tevent_queue *queue) +{ + return queue->length; +} -- cgit From c5e062ed74ec7e13e03ed24e9e4d2ced5351f141 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 26 Feb 2009 14:34:38 +0100 Subject: s3: fix the build JOB_STATUS_BLOCKED -> JOB_STATUS_BLOCKED_DEVQ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Günther, please check... Michael --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7179184b73..49bd5ac8ba 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -447,7 +447,7 @@ static const struct { { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT }, { LPQ_PRINTED, JOB_STATUS_PRINTED }, { LPQ_DELETED, JOB_STATUS_DELETED }, - { LPQ_BLOCKED, JOB_STATUS_BLOCKED }, + { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ }, { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION }, { -1, 0 } }; -- cgit From b934f509ed222eb49e8b24ca111361e563434646 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 15:36:16 +0100 Subject: lib/torture: fix depency to map_nt_error_from_unix() This should fix the build on Mac OS 10 metze --- lib/torture/config.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/torture/config.mk b/lib/torture/config.mk index abd89260f6..b4ad9ae17f 100644 --- a/lib/torture/config.mk +++ b/lib/torture/config.mk @@ -3,7 +3,9 @@ PUBLIC_DEPENDENCIES = \ LIBSAMBA-HOSTCONFIG \ LIBSAMBA-UTIL \ - LIBTALLOC + LIBSAMBA-ERRORS \ + LIBTALLOC \ + LIBTEVENT CFLAGS = -I$(libtorturesrcdir) -I$(libtorturesrcdir)/../ torture_VERSION = 0.0.1 -- cgit From bcadb77c18f9ed9be22762871617f1a12294e88c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Feb 2009 10:13:57 -0800 Subject: Add another torture test inspired by George @ Apple. Inside a directory, keep a file open and then renaming the directory should fail with ACCESS_DENIED. This is connected to the test case where the close was failing due to a delayed write on a file not being able to succeed when Samba allowed the containing directory to be renamed. I will fix this in the server shortly (this should be done across connections also but with will be very hard in Samba - would need a full scan of the open file db on every directory rename) - so I will fix for the local case first (scanning local file opens inside an smbd is cheap). Jeremy. --- source4/torture/raw/rename.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/source4/torture/raw/rename.c b/source4/torture/raw/rename.c index 9d629f0bbf..951d91a684 100644 --- a/source4/torture/raw/rename.c +++ b/source4/torture/raw/rename.c @@ -516,6 +516,91 @@ done: return ret; } +/* + test dir rename. +*/ +static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli) +{ + union smb_open io; + union smb_rename ren_io; + NTSTATUS status; + const char *dname1 = BASEDIR "\\dir_for_rename"; + const char *dname2 = BASEDIR "\\renamed_dir"; + const char *fname = BASEDIR "\\dir_for_rename\\file.txt"; + bool ret = true; + int fnum = -1; + + printf("Checking rename on a directory containing an open file.\n"); + + if (!torture_setup_dir(cli, BASEDIR)) { + return false; + } + + /* create a directory */ + smbcli_rmdir(cli->tree, dname1); + smbcli_rmdir(cli->tree, dname2); + smbcli_unlink(cli->tree, dname1); + smbcli_unlink(cli->tree, dname2); + + ZERO_STRUCT(io); + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; + io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; + io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + io.ntcreatex.in.fname = dname1; + status = smb_raw_open(cli->tree, tctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + fnum = io.ntcreatex.out.file.fnum; + smbcli_close(cli->tree, fnum); + + /* Now create and hold open a file. */ + ZERO_STRUCT(io); + + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname; + + /* Create the file. */ + + status = smb_raw_open(cli->tree, tctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + + /* Now try and rename the directory. */ + + ZERO_STRUCT(ren_io); + ren_io.generic.level = RAW_RENAME_RENAME; + ren_io.rename.in.pattern1 = dname1; + ren_io.rename.in.pattern2 = dname2; + ren_io.rename.in.attrib = 0; + + status = smb_raw_rename(cli->tree, &ren_io); + CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); + +done: + + if (fnum != -1) { + smbcli_close(cli->tree, fnum); + } + smb_raw_exit(cli->session); + smbcli_deltree(cli->tree, BASEDIR); + return ret; +} + extern bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2); extern bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1); @@ -533,6 +618,7 @@ struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx) torture_suite_add_1smb_test(suite, "nttransrename", test_nttransrename); torture_suite_add_1smb_test(suite, "ntrename", test_ntrename); torture_suite_add_1smb_test(suite, "osxrename", test_osxrename); + torture_suite_add_1smb_test(suite, "directory rename", test_dir_rename); return suite; } -- cgit From 3121249243f52dcbf8083f5ff137bd580515efa7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Feb 2009 11:42:23 -0800 Subject: Make us pass the RAW-RENAME torture test I just added. Inside a directory, keep a file open and then renaming the directory should fail with ACCESS_DENIED. Jeremy. --- source3/include/proto.h | 1 + source3/smbd/files.c | 43 +++++++++++++++++++++++++++++++++++++++++++ source3/smbd/reply.c | 10 ++++++++++ 3 files changed, 54 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 27b4ce9604..ce31640272 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6520,6 +6520,7 @@ files_struct *file_find_fsp(files_struct *orig_fsp); files_struct *file_find_di_first(struct file_id id); files_struct *file_find_di_next(files_struct *start_fsp); files_struct *file_find_print(void); +bool file_find_subpath(files_struct *dir_fsp); void file_sync_all(connection_struct *conn); void file_free(struct smb_request *req, files_struct *fsp); files_struct *file_fnum(uint16 fnum); diff --git a/source3/smbd/files.c b/source3/smbd/files.c index efaadffc06..36e80a086a 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -355,6 +355,49 @@ files_struct *file_find_print(void) return NULL; } +/**************************************************************************** + Find any fsp open with a pathname below that of an already open path. +****************************************************************************/ + +bool file_find_subpath(files_struct *dir_fsp) +{ + files_struct *fsp; + size_t dlen; + char *d_fullname = talloc_asprintf(talloc_tos(), + "%s/%s", + dir_fsp->conn->connectpath, + dir_fsp->fsp_name); + + if (!d_fullname) { + return false; + } + + dlen = strlen(d_fullname); + + for (fsp=Files;fsp;fsp=fsp->next) { + char *d1_fullname; + + if (fsp == dir_fsp) { + continue; + } + + d1_fullname = talloc_asprintf(talloc_tos(), + "%s/%s", + fsp->conn->connectpath, + fsp->fsp_name); + + if (strnequal(d_fullname, d1_fullname, dlen)) { + TALLOC_FREE(d_fullname); + TALLOC_FREE(d1_fullname); + return true; + } + TALLOC_FREE(d1_fullname); + } + + TALLOC_FREE(d_fullname); + return false; +} + /**************************************************************************** Sync open files on a connection. ****************************************************************************/ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 80ed019e0f..22e4c1aad7 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2214,6 +2214,16 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp, } if (S_ISDIR(pst->st_mode)) { + if (fsp->posix_open) { + return NT_STATUS_OK; + } + + /* If no pathnames are open below this + directory, allow the rename. */ + + if (file_find_subpath(fsp)) { + return NT_STATUS_ACCESS_DENIED; + } return NT_STATUS_OK; } -- cgit From fe8cf69ec644f399d4b41c21b74703e0e500e092 Mon Sep 17 00:00:00 2001 From: Bjƶrn Jacke Date: Thu, 26 Feb 2009 16:32:57 +0100 Subject: don't hardcode python path Signed-off-by: Michael Adam --- source4/selftest/tests.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source4/selftest/tests.sh b/source4/selftest/tests.sh index 36e3bbe364..99e530ec38 100755 --- a/source4/selftest/tests.sh +++ b/source4/selftest/tests.sh @@ -23,6 +23,11 @@ then PERL=perl fi +if [ ! -n "$PYTHON" ] +then + PYTHON=python +fi + plantest() { name=$1 env=$2 @@ -394,7 +399,6 @@ then plantest "nss.test using winbind" member $VALGRIND $nsstest4 $samba4bindir/shared/libnss_winbind.so fi -PYTHON=/usr/bin/python SUBUNITRUN="$VALGRIND $PYTHON $samba4srcdir/scripting/bin/subunitrun" plantest "ldb.python" none PYTHONPATH="$PYTHONPATH:$samba4srcdir/lib/ldb/tests/python/" $SUBUNITRUN api plantest "credentials.python" none PYTHONPATH="$PYTHONPATH:$samba4srcdir/auth/credentials/tests" $SUBUNITRUN bindings -- cgit From dec1410b10106242ed3dcba522cb4d9914ea92a8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 15:29:23 +0100 Subject: spoolss: add spoolss_JobInfo2, JobInfo3 and JobInfo4 (new in vista). Guenther --- librpc/idl/spoolss.idl | 66 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index f356294d72..75b3bc00f0 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -412,13 +412,73 @@ import "misc.idl", "security.idl", "winreg.idl"; uint32 position; uint32 total_pages; uint32 pages_printed; - spoolss_Time time; + spoolss_Time submitted; } spoolss_JobInfo1; + typedef struct { + uint32 job_id; + [relative] nstring *printer_name; + [relative] nstring *server_name; + [relative] nstring *user_name; + [relative] nstring *document_name; + [relative] nstring *notify_name; + [relative] nstring *data_type; + [relative] nstring *print_processor; + [relative] nstring *parameters; + [relative] nstring *driver_name; + [relative] spoolss_DeviceMode *devmode; + [relative] nstring *text_status; + [relative] security_descriptor *secdesc; + spoolss_JobStatus status; + uint32 priority; + uint32 position; + uint32 start_time; + uint32 until_time; + uint32 total_pages; + uint32 size; + spoolss_Time submitted; + uint32 time; + uint32 pages_printed; + } spoolss_JobInfo2; + + typedef struct { + uint32 job_id; + uint32 next_job_id; + uint32 reserved; + } spoolss_JobInfo3; + + typedef struct { + uint32 job_id; + [relative] nstring *printer_name; + [relative] nstring *server_name; + [relative] nstring *user_name; + [relative] nstring *document_name; + [relative] nstring *notify_name; + [relative] nstring *data_type; + [relative] nstring *print_processor; + [relative] nstring *parameters; + [relative] nstring *driver_name; + [relative] spoolss_DeviceMode *devmode; + [relative] nstring *text_status; + [relative] security_descriptor *secdesc; + spoolss_JobStatus status; + uint32 priority; + uint32 position; + uint32 start_time; + uint32 until_time; + uint32 total_pages; + uint32 size; + spoolss_Time submitted; + uint32 time; + uint32 pages_printed; + uint32 size_high; + } spoolss_JobInfo4; + typedef [nodiscriminant,relative_base,public] union { [case(1)] spoolss_JobInfo1 info1; - [case(2)]; /* TODO */ - [case(3)]; /* TODO */ + [case(2)] spoolss_JobInfo2 info2; + [case(3)] spoolss_JobInfo3 info3; + [case(4)] spoolss_JobInfo4 info4; [default]; } spoolss_JobInfo; -- cgit From d42f833acee7c3c5a124631a5a6e9e2ad69d8059 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 15:52:51 +0100 Subject: spoolss: add 2 new SPOOLSS_JOB_CONTROL values. Guenther --- librpc/idl/spoolss.idl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 75b3bc00f0..855c23711e 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -494,7 +494,9 @@ import "misc.idl", "security.idl", "winreg.idl"; SPOOLSS_JOB_CONTROL_RESTART = 4, SPOOLSS_JOB_CONTROL_DELETE = 5, SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER = 6, - SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED = 7 + SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED = 7, + SPOOLSS_JOB_CONTROL_RETAIN = 8, + SPOOLSS_JOB_CONTROL_RELEASE = 9 } spoolss_JobControl; WERROR spoolss_SetJob( -- cgit From 417f920e0784cb62ebe5bee02cd5e8eb44bf34c8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 22:01:55 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 1333 +++++++++++++++++++++++++++++++++++++++++- librpc/gen_ndr/ndr_spoolss.h | 3 + librpc/gen_ndr/spoolss.h | 70 ++- 3 files changed, 1398 insertions(+), 8 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index f9d4461255..072e9d55d0 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -2600,7 +2600,1042 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->total_pages)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->pages_printed)); - NDR_CHECK(ndr_push_spoolss_Time(ndr, NDR_SCALARS, &r->time)); + NDR_CHECK(ndr_push_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->printer_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->printer_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->printer_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->server_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->server_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->server_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->user_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->user_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->user_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->document_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->document_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->document_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->data_type) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->data_type)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->data_type)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->text_status) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->text_status)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->text_status)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo1 *r) +{ + uint32_t _ptr_printer_name; + TALLOC_CTX *_mem_save_printer_name_0; + uint32_t _ptr_server_name; + TALLOC_CTX *_mem_save_server_name_0; + uint32_t _ptr_user_name; + TALLOC_CTX *_mem_save_user_name_0; + uint32_t _ptr_document_name; + TALLOC_CTX *_mem_save_document_name_0; + uint32_t _ptr_data_type; + TALLOC_CTX *_mem_save_data_type_0; + uint32_t _ptr_text_status; + TALLOC_CTX *_mem_save_text_status_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_printer_name)); + if (_ptr_printer_name) { + NDR_PULL_ALLOC(ndr, r->printer_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->printer_name, _ptr_printer_name)); + } else { + r->printer_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_server_name)); + if (_ptr_server_name) { + NDR_PULL_ALLOC(ndr, r->server_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->server_name, _ptr_server_name)); + } else { + r->server_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_user_name)); + if (_ptr_user_name) { + NDR_PULL_ALLOC(ndr, r->user_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->user_name, _ptr_user_name)); + } else { + r->user_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_document_name)); + if (_ptr_document_name) { + NDR_PULL_ALLOC(ndr, r->document_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->document_name, _ptr_document_name)); + } else { + r->document_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data_type)); + if (_ptr_data_type) { + NDR_PULL_ALLOC(ndr, r->data_type); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->data_type, _ptr_data_type)); + } else { + r->data_type = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_text_status)); + if (_ptr_text_status) { + NDR_PULL_ALLOC(ndr, r->text_status); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->text_status, _ptr_text_status)); + } else { + r->text_status = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pages_printed)); + NDR_CHECK(ndr_pull_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->printer_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->printer_name)); + _mem_save_printer_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->printer_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->printer_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_printer_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->server_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->server_name)); + _mem_save_server_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->server_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->server_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->user_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->user_name)); + _mem_save_user_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->user_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->user_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_user_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->document_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->document_name)); + _mem_save_document_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->document_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->document_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_document_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->data_type) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->data_type)); + _mem_save_data_type_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->data_type, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->data_type)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_type_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->text_status) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->text_status)); + _mem_save_text_status_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->text_status, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->text_status)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_text_status_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_JobInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo1 *r) +{ + ndr_print_struct(ndr, name, "spoolss_JobInfo1"); + ndr->depth++; + ndr_print_uint32(ndr, "job_id", r->job_id); + ndr_print_ptr(ndr, "printer_name", r->printer_name); + ndr->depth++; + if (r->printer_name) { + ndr_print_string(ndr, "printer_name", r->printer_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "server_name", r->server_name); + ndr->depth++; + if (r->server_name) { + ndr_print_string(ndr, "server_name", r->server_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "user_name", r->user_name); + ndr->depth++; + if (r->user_name) { + ndr_print_string(ndr, "user_name", r->user_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "document_name", r->document_name); + ndr->depth++; + if (r->document_name) { + ndr_print_string(ndr, "document_name", r->document_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "data_type", r->data_type); + ndr->depth++; + if (r->data_type) { + ndr_print_string(ndr, "data_type", r->data_type); + } + ndr->depth--; + ndr_print_ptr(ndr, "text_status", r->text_status); + ndr->depth++; + if (r->text_status) { + ndr_print_string(ndr, "text_status", r->text_status); + } + ndr->depth--; + ndr_print_spoolss_JobStatus(ndr, "status", r->status); + ndr_print_uint32(ndr, "priority", r->priority); + ndr_print_uint32(ndr, "position", r->position); + ndr_print_uint32(ndr, "total_pages", r->total_pages); + ndr_print_uint32(ndr, "pages_printed", r->pages_printed); + ndr_print_spoolss_Time(ndr, "submitted", &r->submitted); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_spoolss_JobInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo2 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->job_id)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->printer_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->server_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->user_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->document_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->notify_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->data_type)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->print_processor)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->parameters)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->driver_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->devmode)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->text_status)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->secdesc)); + NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->status)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->priority)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->start_time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->until_time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->total_pages)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size)); + NDR_CHECK(ndr_push_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->pages_printed)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->printer_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->printer_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->printer_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->server_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->server_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->server_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->user_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->user_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->user_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->document_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->document_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->document_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->notify_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->notify_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->notify_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->data_type) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->data_type)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->data_type)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->print_processor) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->print_processor)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->print_processor)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->parameters) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->parameters)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->parameters)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->driver_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->driver_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->driver_name)); + } + ndr->flags = _flags_save_string; + } + if (r->devmode) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->devmode)); + NDR_CHECK(ndr_push_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->text_status) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->text_status)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->text_status)); + } + ndr->flags = _flags_save_string; + } + if (r->secdesc) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->secdesc)); + NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_JobInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo2 *r) +{ + uint32_t _ptr_printer_name; + TALLOC_CTX *_mem_save_printer_name_0; + uint32_t _ptr_server_name; + TALLOC_CTX *_mem_save_server_name_0; + uint32_t _ptr_user_name; + TALLOC_CTX *_mem_save_user_name_0; + uint32_t _ptr_document_name; + TALLOC_CTX *_mem_save_document_name_0; + uint32_t _ptr_notify_name; + TALLOC_CTX *_mem_save_notify_name_0; + uint32_t _ptr_data_type; + TALLOC_CTX *_mem_save_data_type_0; + uint32_t _ptr_print_processor; + TALLOC_CTX *_mem_save_print_processor_0; + uint32_t _ptr_parameters; + TALLOC_CTX *_mem_save_parameters_0; + uint32_t _ptr_driver_name; + TALLOC_CTX *_mem_save_driver_name_0; + uint32_t _ptr_devmode; + TALLOC_CTX *_mem_save_devmode_0; + uint32_t _ptr_text_status; + TALLOC_CTX *_mem_save_text_status_0; + uint32_t _ptr_secdesc; + TALLOC_CTX *_mem_save_secdesc_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_printer_name)); + if (_ptr_printer_name) { + NDR_PULL_ALLOC(ndr, r->printer_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->printer_name, _ptr_printer_name)); + } else { + r->printer_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_server_name)); + if (_ptr_server_name) { + NDR_PULL_ALLOC(ndr, r->server_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->server_name, _ptr_server_name)); + } else { + r->server_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_user_name)); + if (_ptr_user_name) { + NDR_PULL_ALLOC(ndr, r->user_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->user_name, _ptr_user_name)); + } else { + r->user_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_document_name)); + if (_ptr_document_name) { + NDR_PULL_ALLOC(ndr, r->document_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->document_name, _ptr_document_name)); + } else { + r->document_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_notify_name)); + if (_ptr_notify_name) { + NDR_PULL_ALLOC(ndr, r->notify_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->notify_name, _ptr_notify_name)); + } else { + r->notify_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data_type)); + if (_ptr_data_type) { + NDR_PULL_ALLOC(ndr, r->data_type); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->data_type, _ptr_data_type)); + } else { + r->data_type = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_print_processor)); + if (_ptr_print_processor) { + NDR_PULL_ALLOC(ndr, r->print_processor); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->print_processor, _ptr_print_processor)); + } else { + r->print_processor = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_parameters)); + if (_ptr_parameters) { + NDR_PULL_ALLOC(ndr, r->parameters); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->parameters, _ptr_parameters)); + } else { + r->parameters = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_driver_name)); + if (_ptr_driver_name) { + NDR_PULL_ALLOC(ndr, r->driver_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->driver_name, _ptr_driver_name)); + } else { + r->driver_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_devmode)); + if (_ptr_devmode) { + NDR_PULL_ALLOC(ndr, r->devmode); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->devmode, _ptr_devmode)); + } else { + r->devmode = NULL; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_text_status)); + if (_ptr_text_status) { + NDR_PULL_ALLOC(ndr, r->text_status); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->text_status, _ptr_text_status)); + } else { + r->text_status = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_secdesc)); + if (_ptr_secdesc) { + NDR_PULL_ALLOC(ndr, r->secdesc); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->secdesc, _ptr_secdesc)); + } else { + r->secdesc = NULL; + } + NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->start_time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->until_time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pages_printed)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->printer_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->printer_name)); + _mem_save_printer_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->printer_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->printer_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_printer_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->server_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->server_name)); + _mem_save_server_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->server_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->server_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->user_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->user_name)); + _mem_save_user_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->user_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->user_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_user_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->document_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->document_name)); + _mem_save_document_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->document_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->document_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_document_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->notify_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->notify_name)); + _mem_save_notify_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->notify_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->notify_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_notify_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->data_type) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->data_type)); + _mem_save_data_type_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->data_type, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->data_type)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_type_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->print_processor) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->print_processor)); + _mem_save_print_processor_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->print_processor, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->print_processor)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_print_processor_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->parameters) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->parameters)); + _mem_save_parameters_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->parameters, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->parameters)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_parameters_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->driver_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->driver_name)); + _mem_save_driver_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->driver_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->driver_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_driver_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + if (r->devmode) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->devmode)); + _mem_save_devmode_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->devmode, 0); + NDR_CHECK(ndr_pull_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_0, 0); + ndr->offset = _relative_save_offset; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->text_status) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->text_status)); + _mem_save_text_status_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->text_status, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->text_status)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_text_status_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + if (r->secdesc) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->secdesc)); + _mem_save_secdesc_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->secdesc, 0); + NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_secdesc_0, 0); + ndr->offset = _relative_save_offset; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_JobInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo2 *r) +{ + ndr_print_struct(ndr, name, "spoolss_JobInfo2"); + ndr->depth++; + ndr_print_uint32(ndr, "job_id", r->job_id); + ndr_print_ptr(ndr, "printer_name", r->printer_name); + ndr->depth++; + if (r->printer_name) { + ndr_print_string(ndr, "printer_name", r->printer_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "server_name", r->server_name); + ndr->depth++; + if (r->server_name) { + ndr_print_string(ndr, "server_name", r->server_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "user_name", r->user_name); + ndr->depth++; + if (r->user_name) { + ndr_print_string(ndr, "user_name", r->user_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "document_name", r->document_name); + ndr->depth++; + if (r->document_name) { + ndr_print_string(ndr, "document_name", r->document_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "notify_name", r->notify_name); + ndr->depth++; + if (r->notify_name) { + ndr_print_string(ndr, "notify_name", r->notify_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "data_type", r->data_type); + ndr->depth++; + if (r->data_type) { + ndr_print_string(ndr, "data_type", r->data_type); + } + ndr->depth--; + ndr_print_ptr(ndr, "print_processor", r->print_processor); + ndr->depth++; + if (r->print_processor) { + ndr_print_string(ndr, "print_processor", r->print_processor); + } + ndr->depth--; + ndr_print_ptr(ndr, "parameters", r->parameters); + ndr->depth++; + if (r->parameters) { + ndr_print_string(ndr, "parameters", r->parameters); + } + ndr->depth--; + ndr_print_ptr(ndr, "driver_name", r->driver_name); + ndr->depth++; + if (r->driver_name) { + ndr_print_string(ndr, "driver_name", r->driver_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "devmode", r->devmode); + ndr->depth++; + if (r->devmode) { + ndr_print_spoolss_DeviceMode(ndr, "devmode", r->devmode); + } + ndr->depth--; + ndr_print_ptr(ndr, "text_status", r->text_status); + ndr->depth++; + if (r->text_status) { + ndr_print_string(ndr, "text_status", r->text_status); + } + ndr->depth--; + ndr_print_ptr(ndr, "secdesc", r->secdesc); + ndr->depth++; + if (r->secdesc) { + ndr_print_security_descriptor(ndr, "secdesc", r->secdesc); + } + ndr->depth--; + ndr_print_spoolss_JobStatus(ndr, "status", r->status); + ndr_print_uint32(ndr, "priority", r->priority); + ndr_print_uint32(ndr, "position", r->position); + ndr_print_uint32(ndr, "start_time", r->start_time); + ndr_print_uint32(ndr, "until_time", r->until_time); + ndr_print_uint32(ndr, "total_pages", r->total_pages); + ndr_print_uint32(ndr, "size", r->size); + ndr_print_spoolss_Time(ndr, "submitted", &r->submitted); + ndr_print_uint32(ndr, "time", r->time); + ndr_print_uint32(ndr, "pages_printed", r->pages_printed); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_spoolss_JobInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo3 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->job_id)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->next_job_id)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->reserved)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_JobInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo3 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->next_job_id)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->reserved)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_JobInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo3 *r) +{ + ndr_print_struct(ndr, name, "spoolss_JobInfo3"); + ndr->depth++; + ndr_print_uint32(ndr, "job_id", r->job_id); + ndr_print_uint32(ndr, "next_job_id", r->next_job_id); + ndr_print_uint32(ndr, "reserved", r->reserved); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_spoolss_JobInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfo4 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->job_id)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->printer_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->server_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->user_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->document_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->notify_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->data_type)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->print_processor)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->parameters)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->driver_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->devmode)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->text_status)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->secdesc)); + NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->status)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->priority)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->start_time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->until_time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->total_pages)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size)); + NDR_CHECK(ndr_push_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->pages_printed)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size_high)); } if (ndr_flags & NDR_BUFFERS) { { @@ -2639,6 +3674,15 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr } ndr->flags = _flags_save_string; } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->notify_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->notify_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->notify_name)); + } + ndr->flags = _flags_save_string; + } { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); @@ -2648,6 +3692,37 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr } ndr->flags = _flags_save_string; } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->print_processor) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->print_processor)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->print_processor)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->parameters) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->parameters)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->parameters)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->driver_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->driver_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->driver_name)); + } + ndr->flags = _flags_save_string; + } + if (r->devmode) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->devmode)); + NDR_CHECK(ndr_push_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); + } { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); @@ -2657,11 +3732,15 @@ static enum ndr_err_code ndr_push_spoolss_JobInfo1(struct ndr_push *ndr, int ndr } ndr->flags = _flags_save_string; } + if (r->secdesc) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->secdesc)); + NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); + } } return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo1 *r) +static enum ndr_err_code ndr_pull_spoolss_JobInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_JobInfo4 *r) { uint32_t _ptr_printer_name; TALLOC_CTX *_mem_save_printer_name_0; @@ -2671,10 +3750,22 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr TALLOC_CTX *_mem_save_user_name_0; uint32_t _ptr_document_name; TALLOC_CTX *_mem_save_document_name_0; + uint32_t _ptr_notify_name; + TALLOC_CTX *_mem_save_notify_name_0; uint32_t _ptr_data_type; TALLOC_CTX *_mem_save_data_type_0; + uint32_t _ptr_print_processor; + TALLOC_CTX *_mem_save_print_processor_0; + uint32_t _ptr_parameters; + TALLOC_CTX *_mem_save_parameters_0; + uint32_t _ptr_driver_name; + TALLOC_CTX *_mem_save_driver_name_0; + uint32_t _ptr_devmode; + TALLOC_CTX *_mem_save_devmode_0; uint32_t _ptr_text_status; TALLOC_CTX *_mem_save_text_status_0; + uint32_t _ptr_secdesc; + TALLOC_CTX *_mem_save_secdesc_0; if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id)); @@ -2726,6 +3817,18 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr } ndr->flags = _flags_save_string; } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_notify_name)); + if (_ptr_notify_name) { + NDR_PULL_ALLOC(ndr, r->notify_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->notify_name, _ptr_notify_name)); + } else { + r->notify_name = NULL; + } + ndr->flags = _flags_save_string; + } { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); @@ -2738,6 +3841,49 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr } ndr->flags = _flags_save_string; } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_print_processor)); + if (_ptr_print_processor) { + NDR_PULL_ALLOC(ndr, r->print_processor); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->print_processor, _ptr_print_processor)); + } else { + r->print_processor = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_parameters)); + if (_ptr_parameters) { + NDR_PULL_ALLOC(ndr, r->parameters); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->parameters, _ptr_parameters)); + } else { + r->parameters = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_driver_name)); + if (_ptr_driver_name) { + NDR_PULL_ALLOC(ndr, r->driver_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->driver_name, _ptr_driver_name)); + } else { + r->driver_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_devmode)); + if (_ptr_devmode) { + NDR_PULL_ALLOC(ndr, r->devmode); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->devmode, _ptr_devmode)); + } else { + r->devmode = NULL; + } { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); @@ -2750,12 +3896,24 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr } ndr->flags = _flags_save_string; } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_secdesc)); + if (_ptr_secdesc) { + NDR_PULL_ALLOC(ndr, r->secdesc); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->secdesc, _ptr_secdesc)); + } else { + r->secdesc = NULL; + } NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->start_time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->until_time)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->time)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pages_printed)); - NDR_CHECK(ndr_pull_spoolss_Time(ndr, NDR_SCALARS, &r->time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size_high)); } if (ndr_flags & NDR_BUFFERS) { { @@ -2818,6 +3976,21 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr } ndr->flags = _flags_save_string; } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->notify_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->notify_name)); + _mem_save_notify_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->notify_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->notify_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_notify_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); @@ -2833,6 +4006,61 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr } ndr->flags = _flags_save_string; } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->print_processor) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->print_processor)); + _mem_save_print_processor_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->print_processor, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->print_processor)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_print_processor_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->parameters) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->parameters)); + _mem_save_parameters_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->parameters, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->parameters)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_parameters_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->driver_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->driver_name)); + _mem_save_driver_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->driver_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->driver_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_driver_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + if (r->devmode) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->devmode)); + _mem_save_devmode_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->devmode, 0); + NDR_CHECK(ndr_pull_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_0, 0); + ndr->offset = _relative_save_offset; + } { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); @@ -2848,13 +4076,23 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfo1(struct ndr_pull *ndr, int ndr } ndr->flags = _flags_save_string; } + if (r->secdesc) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->secdesc)); + _mem_save_secdesc_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->secdesc, 0); + NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_secdesc_0, 0); + ndr->offset = _relative_save_offset; + } } return NDR_ERR_SUCCESS; } -_PUBLIC_ void ndr_print_spoolss_JobInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo1 *r) +_PUBLIC_ void ndr_print_spoolss_JobInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo4 *r) { - ndr_print_struct(ndr, name, "spoolss_JobInfo1"); + ndr_print_struct(ndr, name, "spoolss_JobInfo4"); ndr->depth++; ndr_print_uint32(ndr, "job_id", r->job_id); ndr_print_ptr(ndr, "printer_name", r->printer_name); @@ -2881,24 +4119,65 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo1(struct ndr_print *ndr, const char *name ndr_print_string(ndr, "document_name", r->document_name); } ndr->depth--; + ndr_print_ptr(ndr, "notify_name", r->notify_name); + ndr->depth++; + if (r->notify_name) { + ndr_print_string(ndr, "notify_name", r->notify_name); + } + ndr->depth--; ndr_print_ptr(ndr, "data_type", r->data_type); ndr->depth++; if (r->data_type) { ndr_print_string(ndr, "data_type", r->data_type); } ndr->depth--; + ndr_print_ptr(ndr, "print_processor", r->print_processor); + ndr->depth++; + if (r->print_processor) { + ndr_print_string(ndr, "print_processor", r->print_processor); + } + ndr->depth--; + ndr_print_ptr(ndr, "parameters", r->parameters); + ndr->depth++; + if (r->parameters) { + ndr_print_string(ndr, "parameters", r->parameters); + } + ndr->depth--; + ndr_print_ptr(ndr, "driver_name", r->driver_name); + ndr->depth++; + if (r->driver_name) { + ndr_print_string(ndr, "driver_name", r->driver_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "devmode", r->devmode); + ndr->depth++; + if (r->devmode) { + ndr_print_spoolss_DeviceMode(ndr, "devmode", r->devmode); + } + ndr->depth--; ndr_print_ptr(ndr, "text_status", r->text_status); ndr->depth++; if (r->text_status) { ndr_print_string(ndr, "text_status", r->text_status); } ndr->depth--; + ndr_print_ptr(ndr, "secdesc", r->secdesc); + ndr->depth++; + if (r->secdesc) { + ndr_print_security_descriptor(ndr, "secdesc", r->secdesc); + } + ndr->depth--; ndr_print_spoolss_JobStatus(ndr, "status", r->status); ndr_print_uint32(ndr, "priority", r->priority); ndr_print_uint32(ndr, "position", r->position); + ndr_print_uint32(ndr, "start_time", r->start_time); + ndr_print_uint32(ndr, "until_time", r->until_time); ndr_print_uint32(ndr, "total_pages", r->total_pages); + ndr_print_uint32(ndr, "size", r->size); + ndr_print_spoolss_Time(ndr, "submitted", &r->submitted); + ndr_print_uint32(ndr, "time", r->time); ndr_print_uint32(ndr, "pages_printed", r->pages_printed); - ndr_print_spoolss_Time(ndr, "time", &r->time); + ndr_print_uint32(ndr, "size_high", r->size_high); ndr->depth--; } @@ -2915,9 +4194,21 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_JobInfo(struct ndr_push *ndr, int nd break; } case 2: { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_JobInfo2(ndr, NDR_SCALARS, &r->info2)); break; } case 3: { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_JobInfo3(ndr, NDR_SCALARS, &r->info3)); + break; } + + case 4: { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_JobInfo4(ndr, NDR_SCALARS, &r->info4)); break; } default: { @@ -2934,11 +4225,16 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_JobInfo(struct ndr_push *ndr, int nd break; case 2: + NDR_CHECK(ndr_push_spoolss_JobInfo2(ndr, NDR_BUFFERS, &r->info2)); break; case 3: break; + case 4: + NDR_CHECK(ndr_push_spoolss_JobInfo4(ndr, NDR_BUFFERS, &r->info4)); + break; + default: break; @@ -2962,9 +4258,21 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo(struct ndr_pull *ndr, int nd break; } case 2: { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_JobInfo2(ndr, NDR_SCALARS, &r->info2)); break; } case 3: { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_JobInfo3(ndr, NDR_SCALARS, &r->info3)); + break; } + + case 4: { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_JobInfo4(ndr, NDR_SCALARS, &r->info4)); break; } default: { @@ -2980,11 +4288,16 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_JobInfo(struct ndr_pull *ndr, int nd break; case 2: + NDR_CHECK(ndr_pull_spoolss_JobInfo2(ndr, NDR_BUFFERS, &r->info2)); break; case 3: break; + case 4: + NDR_CHECK(ndr_pull_spoolss_JobInfo4(ndr, NDR_BUFFERS, &r->info4)); + break; + default: break; @@ -3005,9 +4318,15 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo(struct ndr_print *ndr, const char *name, break; case 2: + ndr_print_spoolss_JobInfo2(ndr, "info2", &r->info2); break; case 3: + ndr_print_spoolss_JobInfo3(ndr, "info3", &r->info3); + break; + + case 4: + ndr_print_spoolss_JobInfo4(ndr, "info4", &r->info4); break; default: @@ -3080,6 +4399,8 @@ _PUBLIC_ void ndr_print_spoolss_JobControl(struct ndr_print *ndr, const char *na case SPOOLSS_JOB_CONTROL_DELETE: val = "SPOOLSS_JOB_CONTROL_DELETE"; break; case SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER: val = "SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER"; break; case SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED: val = "SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED"; break; + case SPOOLSS_JOB_CONTROL_RETAIN: val = "SPOOLSS_JOB_CONTROL_RETAIN"; break; + case SPOOLSS_JOB_CONTROL_RELEASE: val = "SPOOLSS_JOB_CONTROL_RELEASE"; break; } ndr_print_enum(ndr, name, "ENUM", val, r); } diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index bf144229d8..f18c0fd77e 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -237,6 +237,9 @@ void ndr_print_spoolss_PrinterInfo(struct ndr_print *ndr, const char *name, cons void ndr_print_spoolss_DevmodeContainer(struct ndr_print *ndr, const char *name, const struct spoolss_DevmodeContainer *r); void ndr_print_spoolss_JobStatus(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_spoolss_JobInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo1 *r); +void ndr_print_spoolss_JobInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo2 *r); +void ndr_print_spoolss_JobInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo3 *r); +void ndr_print_spoolss_JobInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfo4 *r); enum ndr_err_code ndr_push_spoolss_JobInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_JobInfo *r); enum ndr_err_code ndr_pull_spoolss_JobInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_JobInfo *r); void ndr_print_spoolss_JobInfo(struct ndr_print *ndr, const char *name, const union spoolss_JobInfo *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 25162a0f9c..3675b88225 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -401,11 +401,73 @@ struct spoolss_JobInfo1 { uint32_t position; uint32_t total_pages; uint32_t pages_printed; - struct spoolss_Time time; + struct spoolss_Time submitted; +}; + +struct spoolss_JobInfo2 { + uint32_t job_id; + const char * printer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * server_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * user_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * document_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * notify_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * data_type;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * print_processor;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * parameters;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * driver_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + struct spoolss_DeviceMode *devmode;/* [relative] */ + const char * text_status;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + struct security_descriptor *secdesc;/* [relative] */ + uint32_t status; + uint32_t priority; + uint32_t position; + uint32_t start_time; + uint32_t until_time; + uint32_t total_pages; + uint32_t size; + struct spoolss_Time submitted; + uint32_t time; + uint32_t pages_printed; +}; + +struct spoolss_JobInfo3 { + uint32_t job_id; + uint32_t next_job_id; + uint32_t reserved; +}; + +struct spoolss_JobInfo4 { + uint32_t job_id; + const char * printer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * server_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * user_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * document_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * notify_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * data_type;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * print_processor;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * parameters;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * driver_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + struct spoolss_DeviceMode *devmode;/* [relative] */ + const char * text_status;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + struct security_descriptor *secdesc;/* [relative] */ + uint32_t status; + uint32_t priority; + uint32_t position; + uint32_t start_time; + uint32_t until_time; + uint32_t total_pages; + uint32_t size; + struct spoolss_Time submitted; + uint32_t time; + uint32_t pages_printed; + uint32_t size_high; }; union spoolss_JobInfo { struct spoolss_JobInfo1 info1;/* [case] */ + struct spoolss_JobInfo2 info2;/* [case(2)] */ + struct spoolss_JobInfo3 info3;/* [case(3)] */ + struct spoolss_JobInfo4 info4;/* [case(4)] */ }/* [relative_base,nodiscriminant,public] */; struct spoolss_JobInfoContainer { @@ -422,7 +484,9 @@ enum spoolss_JobControl SPOOLSS_JOB_CONTROL_RESTART=4, SPOOLSS_JOB_CONTROL_DELETE=5, SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER=6, - SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED=7 + SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED=7, + SPOOLSS_JOB_CONTROL_RETAIN=8, + SPOOLSS_JOB_CONTROL_RELEASE=9 } #else { __donnot_use_enum_spoolss_JobControl=0x7FFFFFFF} @@ -433,6 +497,8 @@ enum spoolss_JobControl #define SPOOLSS_JOB_CONTROL_DELETE ( 5 ) #define SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER ( 6 ) #define SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED ( 7 ) +#define SPOOLSS_JOB_CONTROL_RETAIN ( 8 ) +#define SPOOLSS_JOB_CONTROL_RELEASE ( 9 ) #endif ; -- cgit From 0445c554d1e112f3721e28072406bd4f63b6aefe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 15:33:57 +0100 Subject: s3-spoolss: add rpccli_spoolss_getjob convenience wrapper. Guenther --- source3/include/proto.h | 7 ++++++ source3/rpc_client/cli_spoolss.c | 52 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index ce31640272..30024a8cb4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5497,6 +5497,13 @@ WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, uint32_t level, uint32_t offered, union spoolss_PrinterInfo *info); +WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t job_id, + uint32_t level, + uint32_t offered, + union spoolss_JobInfo *info); WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 4c1d57e063..8626627308 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -228,6 +228,58 @@ WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, return werror; } +/********************************************************************** + convencience wrapper around rpccli_spoolss_GetJob +**********************************************************************/ + +WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t job_id, + uint32_t level, + uint32_t offered, + union spoolss_JobInfo *info) +{ + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; + + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + } + + status = rpccli_spoolss_GetJob(cli, mem_ctx, + handle, + job_id, + level, + (offered > 0) ? &buffer : NULL, + offered, + info, + &needed, + &werror); + + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + + status = rpccli_spoolss_GetJob(cli, mem_ctx, + handle, + job_id, + level, + &buffer, + offered, + info, + &needed, + &werror); + } + + return werror; +} + + /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ -- cgit From f343ed7319272fc8105ae3edf8039742fc4fe6d9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 15:34:46 +0100 Subject: s3-spoolss: remove old rpccli_spoolss_getjob. Guenther --- source3/include/proto.h | 6 ---- source3/rpc_client/cli_spoolss.c | 67 --------------------------------------- source3/rpc_parse/parse_spoolss.c | 17 ---------- 3 files changed, 90 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 30024a8cb4..5bae973c3d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5520,9 +5520,6 @@ WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, uint32 firstjob, uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr); -WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 jobid, uint32 level, - JOB_INFO_CTR *ctr); WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, const char *valuename, REGISTRY_VALUE *value); @@ -5953,9 +5950,6 @@ bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, uint32 level, RPC_BUFFER *buffer, uint32 offered); -bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, - uint32 jobid, uint32 level, RPC_BUFFER *buffer, - uint32 offered); /* The following definitions come from rpc_server/srv_eventlog_lib.c */ diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 8626627308..d76d20c962 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -1017,73 +1017,6 @@ WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 jobid, uint32 level, - JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETJOB in; - SPOOL_R_GETJOB out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB, - in, out, - qbuf, rbuf, - spoolss_io_q_getjob, - spoolss_io_r_getjob, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB, - in, out, - qbuf, rbuf, - spoolss_io_q_getjob, - spoolss_io_r_getjob, - WERR_GENERAL_FAILURE ); - } - - if (!W_ERROR_IS_OK(out.status)) - return out.status; - - switch(level) { - case 1: - if (!decode_jobs_1(mem_ctx, out.buffer, 1, &ctr->job.job_info_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_jobs_2(mem_ctx, out.buffer, 1, &ctr->job.job_info_2)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, const char *valuename, REGISTRY_VALUE *value) diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index c9c897253a..78c041f863 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -3099,20 +3099,3 @@ bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, return True; } - -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, - uint32 jobid, uint32 level, RPC_BUFFER *buffer, - uint32 offered) -{ - memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); - q_u->jobid = jobid; - q_u->level = level; - q_u->buffer = buffer; - q_u->offered = offered; - - return True; -} -- cgit From a263d8f430383cc94f14cf331db5e21671196032 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 15:33:16 +0100 Subject: s3-rpcclient: use is_valid_policy_hnd before closing handles. Guenther --- source3/rpcclient/cmd_spoolss.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 79cde704d2..72cc40b748 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -2428,7 +2428,6 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, { WERROR result; uint32 level = 1, num_jobs, i; - bool got_hnd = False; const char *printername; POLICY_HND hnd; JOB_INFO_CTR ctr; @@ -2452,8 +2451,6 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - got_hnd = True; - /* Enumerate ports */ result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000, @@ -2477,7 +2474,7 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, } done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2492,7 +2489,6 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, { WERROR result; uint32 i=0, val_needed, data_needed; - bool got_hnd = False; const char *printername; POLICY_HND hnd; @@ -2512,8 +2508,6 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - got_hnd = True; - /* Enumerate data */ result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0, @@ -2531,7 +2525,7 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, result = W_ERROR(ERRsuccess); done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2546,7 +2540,6 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, { WERROR result; uint32 i; - bool got_hnd = False; const char *printername; const char *keyname = NULL; POLICY_HND hnd; @@ -2570,8 +2563,6 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - got_hnd = True; - /* Enumerate subkeys */ if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) @@ -2589,7 +2580,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, TALLOC_FREE( ctr ); done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2603,7 +2594,6 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, const char **argv) { WERROR result; - bool got_hnd = False; const char *printername; const char *keyname = NULL; POLICY_HND hnd; @@ -2630,8 +2620,6 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - got_hnd = True; - /* Enumerate subkeys */ result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL); @@ -2655,7 +2643,7 @@ done: SAFE_FREE(keylist); - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2671,7 +2659,6 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, const char *printername; const char *clientname; POLICY_HND hnd; - bool got_hnd = False; WERROR result; NTSTATUS status; struct spoolss_NotifyOption option; @@ -2695,8 +2682,6 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, goto done; } - got_hnd = True; - /* Create spool options */ option.version = 2; @@ -2748,7 +2733,7 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, } done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; -- cgit From b7b287d41720ec15eff234ffc96c2fa628e8a6e8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 15:35:12 +0100 Subject: s3-rpcclient: add getjob spoolss command. Guenther --- source3/rpcclient/cmd_spoolss.c | 119 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 72cc40b748..c68cf00530 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -2422,6 +2422,47 @@ static void display_job_info_2(JOB_INFO_2 *job) /**************************************************************************** ****************************************************************************/ +static void display_job_info1(struct spoolss_JobInfo1 *r) +{ + printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id, + r->user_name, r->document_name, r->text_status, r->pages_printed, + r->total_pages); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_job_info2(struct spoolss_JobInfo2 *r) +{ + printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", + r->position, r->job_id, + r->user_name, r->document_name, r->text_status, r->pages_printed, + r->total_pages, r->size); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_job_info3(struct spoolss_JobInfo3 *r) +{ + printf("jobid[%d], next_jobid[%d]\n", + r->job_id, r->next_job_id); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_job_info4(struct spoolss_JobInfo4 *r) +{ + printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n", + r->position, r->job_id, + r->user_name, r->document_name, r->text_status, r->pages_printed, + r->total_pages, r->size, r->size_high); +} + +/**************************************************************************** +****************************************************************************/ + static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -2480,6 +2521,83 @@ done: return result; } +/**************************************************************************** +****************************************************************************/ + +static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR result; + const char *printername; + struct policy_handle hnd; + uint32_t job_id; + uint32_t level = 1; + union spoolss_JobInfo info; + + if (argc < 3 || argc > 4) { + printf("Usage: %s printername job_id [level]\n", argv[0]); + return WERR_OK; + } + + job_id = atoi(argv[2]); + + if (argc == 4) { + level = atoi(argv[3]); + } + + /* Open printer handle */ + + RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); + + result = rpccli_spoolss_openprinter_ex(cli, mem_ctx, + printername, + SEC_FLAG_MAXIMUM_ALLOWED, + &hnd); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* Enumerate ports */ + + result = rpccli_spoolss_getjob(cli, mem_ctx, + &hnd, + job_id, + level, + 0, + &info); + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + switch (level) { + case 1: + display_job_info1(&info.info1); + break; + case 2: + display_job_info2(&info.info2); + break; + case 3: + display_job_info3(&info.info3); + break; + case 4: + display_job_info4(&info.info4); + break; + default: + d_printf("unknown info level %d\n", level); + break; + } + +done: + if (is_valid_policy_hnd(&hnd)) { + rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); + } + + return result; +} + + /**************************************************************************** ****************************************************************************/ @@ -2954,6 +3072,7 @@ struct cmd_set spoolss_commands[] = { { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &syntax_spoolss, NULL, "Enumerate printer data for a key", "" }, { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &syntax_spoolss, NULL, "Enumerate printer keys", "" }, { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &syntax_spoolss, NULL, "Enumerate print jobs", "" }, + { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &syntax_spoolss, NULL, "Get print job", "" }, { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &syntax_spoolss, NULL, "Enumerate printer ports", "" }, { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &syntax_spoolss, NULL, "Enumerate installed printer drivers", "" }, { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &syntax_spoolss, NULL, "Enumerate printers", "" }, -- cgit From 61bedb4263a73121bde3fb18295bc0abc4ccbcb2 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Thu, 26 Feb 2009 17:47:32 -0800 Subject: s3: fix guest auth when winbindd is running This fix is very subtle. If a server is configured with "security = share" and "guest ok = yes" and winbindd is running authorization will fail during tree connect. This is due to our inability to map the guest sid S-1-5-21-X-501 to a uid through sid_to_uid(). Winbindd is unaware of the hard coded mapping between this sid and whatever uid the name in lp_guestaccount() is assigned. So sid_to_uid() fails and we exit create_token_from_username() without ever calling pdb_getsampwsid() which IS aware of the hard coded mapping. This patch just reorganizes the code, moving sid_to_uid() down to the block of code in which it is needed, avoiding this early failure. --- source3/auth/auth_util.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 1f00e22a3c..c39aa8501d 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -806,7 +806,7 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info) } /* - * Create an artificial NT token given just a username. (Initially indended + * Create an artificial NT token given just a username. (Initially intended * for force user) * * We go through lookup_name() to avoid problems we had with 'winbind use @@ -859,12 +859,6 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, goto done; } - if (!sid_to_uid(&user_sid, uid)) { - DEBUG(1, ("sid_to_uid for %s (%s) failed\n", - username, sid_string_dbg(&user_sid))); - goto done; - } - if (sid_check_is_in_our_domain(&user_sid)) { bool ret; @@ -922,6 +916,12 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, unix_user: + if (!sid_to_uid(&user_sid, uid)) { + DEBUG(1, ("sid_to_uid for %s (%s) failed\n", + username, sid_string_dbg(&user_sid))); + goto done; + } + uid_to_unix_users_sid(*uid, &user_sid); pass = getpwuid_alloc(tmp_ctx, *uid); -- cgit From 62db0ea0cfe215b83f7ec94b77f10ef49175c7ae Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 27 Feb 2009 11:18:35 +0100 Subject: Use talloc_tos() in regkey_access_check() --- source3/registry/reg_dispatcher.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index 106d38e9a5..f8c382536f 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -161,7 +161,6 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, SEC_DESC *sec_desc; NTSTATUS status; WERROR err; - TALLOC_CTX *mem_ctx; /* use the default security check if the backend has not defined its * own */ @@ -171,30 +170,20 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, granted, token); } - /* - * The secdesc routines can't yet cope with a NULL talloc ctx sanely. - */ - - if (!(mem_ctx = talloc_init("regkey_access_check"))) { - return false; - } - - err = regkey_get_secdesc(mem_ctx, key, &sec_desc); + err = regkey_get_secdesc(talloc_tos(), key, &sec_desc); if (!W_ERROR_IS_OK(err)) { - TALLOC_FREE(mem_ctx); return false; } se_map_generic( &requested, ®_generic_map ); status =se_access_check(sec_desc, token, requested, granted); + TALLOC_FREE(sec_desc); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(mem_ctx); return false; } - TALLOC_FREE(mem_ctx); return NT_STATUS_IS_OK(status); } -- cgit From 670a22852c4d71883292a8361ef1eb0da99088b1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Feb 2009 23:40:58 +0100 Subject: s3-spoolss: use DSPRINT flags instead of SPOOLS_DS flags. Guenther --- source3/include/rpc_spoolss.h | 5 ----- source3/printing/nt_printing.c | 12 ++++++------ source3/rpc_server/srv_spoolss_nt.c | 4 ++-- source3/smbd/server.c | 2 +- source3/utils/net_rpc_printer.c | 20 ++++++++++---------- 5 files changed, 19 insertions(+), 24 deletions(-) diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index a26a315224..798bbf922c 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -428,11 +428,6 @@ typedef struct printer_info_6 } PRINTER_INFO_6; -#define SPOOL_DS_PUBLISH 1 -#define SPOOL_DS_UPDATE 2 -#define SPOOL_DS_UNPUBLISH 4 -#define SPOOL_DS_PENDING 0x80000000 - typedef struct printer_info_7 { UNISTR guid; /* text form of printer guid */ diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index b254ce0b95..d8658e9280 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -3425,8 +3425,8 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) goto done; switch (action) { - case SPOOL_DS_PUBLISH: - case SPOOL_DS_UPDATE: + case DSPRINT_PUBLISH: + case DSPRINT_UPDATE: /* set the DsSpooler info and attributes */ if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) { win_rc = WERR_NOMEM; @@ -3435,7 +3435,7 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED; break; - case SPOOL_DS_UNPUBLISH: + case DSPRINT_UNPUBLISH: printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED; break; default: @@ -3469,11 +3469,11 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) } switch (action) { - case SPOOL_DS_PUBLISH: - case SPOOL_DS_UPDATE: + case DSPRINT_PUBLISH: + case DSPRINT_UPDATE: win_rc = nt_printer_publish_ads(ads, printer); break; - case SPOOL_DS_UNPUBLISH: + case DSPRINT_UNPUBLISH: win_rc = nt_printer_unpublish_ads(ads, printer); break; } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 7a580517d3..814f406e87 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4353,10 +4353,10 @@ static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p strupper_m(guid_str); init_unistr(&printer->guid, guid_str); SAFE_FREE(guid_str); - printer->action = SPOOL_DS_PUBLISH; + printer->action = DSPRINT_PUBLISH; } else { init_unistr(&printer->guid, ""); - printer->action = SPOOL_DS_UNPUBLISH; + printer->action = DSPRINT_UNPUBLISH; } return True; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 346e8973de..538e04938e 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -730,7 +730,7 @@ void reload_printers(void) DEBUG(3, ("removing stale printer %s\n", pname)); if (is_printer_published(NULL, snum, NULL)) - nt_printer_publish(NULL, snum, SPOOL_DS_UNPUBLISH); + nt_printer_publish(NULL, snum, DSPRINT_UNPUBLISH); del_a_printer(pname); lp_killservice(snum); } diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 99012ddf2d..8116764d9b 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -1313,13 +1313,13 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ /* check action and set string */ switch (action) { - case SPOOL_DS_PUBLISH: + case DSPRINT_PUBLISH: action_str = "published"; break; - case SPOOL_DS_UPDATE: + case DSPRINT_UPDATE: action_str = "updated"; break; - case SPOOL_DS_UNPUBLISH: + case DSPRINT_UNPUBLISH: action_str = "unpublished"; break; default: @@ -1369,7 +1369,7 @@ NTSTATUS rpc_printer_publish_publish_internals(struct net_context *c, int argc, const char **argv) { - return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_PUBLISH); + return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_PUBLISH); } NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c, @@ -1381,7 +1381,7 @@ NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c, int argc, const char **argv) { - return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_UNPUBLISH); + return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UNPUBLISH); } NTSTATUS rpc_printer_publish_update_internals(struct net_context *c, @@ -1393,7 +1393,7 @@ NTSTATUS rpc_printer_publish_update_internals(struct net_context *c, int argc, const char **argv) { - return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_UPDATE); + return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UPDATE); } /** @@ -1466,16 +1466,16 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, } state = info.info7.action; switch (state) { - case SPOOL_DS_PUBLISH: + case DSPRINT_PUBLISH: printf("printer [%s] is published", sharename); if (c->opt_verbose) printf(", guid: %s", info.info7.guid); printf("\n"); break; - case SPOOL_DS_UNPUBLISH: + case DSPRINT_UNPUBLISH: printf("printer [%s] is unpublished\n", sharename); break; - case SPOOL_DS_UPDATE: + case DSPRINT_UPDATE: printf("printer [%s] is currently updating\n", sharename); break; default: @@ -2348,7 +2348,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish)) goto done; - info_dst_publish.info7.action = SPOOL_DS_PUBLISH; + info_dst_publish.info7.action = DSPRINT_PUBLISH; /* ignore false from setprinter due to WERR_IO_PENDING */ net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish); -- cgit From d0e31f8cfa20238ab96709797ed903aa425f11de Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 27 Feb 2009 11:27:44 +0100 Subject: spoolss: add spoolss_PortInfo3 and spoolss_PortInfoFF. Guenther --- librpc/idl/spoolss.idl | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 855c23711e..946db7a7bf 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1449,10 +1449,44 @@ import "misc.idl", "security.idl", "winreg.idl"; uint32 reserved; } spoolss_PortInfo2; + typedef [v1_enum] enum { + PORT_STATUS_CLEAR = 0x00000000, + PORT_STATUS_OFFLINE = 0x00000001, + PORT_STATUS_PAPER_JAM = 0x00000002, + PORT_STATUS_PAPER_OUT = 0x00000003, + PORT_STATUS_OUTPUT_BIN_FULL = 0x00000004, + PORT_STATUS_PAPER_PROBLEM = 0x00000005, + PORT_STATUS_NO_TONER = 0x00000006, + PORT_STATUS_DOOR_OPEN = 0x00000007, + PORT_STATUS_USER_INTERVENTION = 0x00000008, + PORT_STATUS_OUT_OF_MEMORY = 0x00000009, + PORT_STATUS_TONER_LOW = 0x0000000A, + PORT_STATUS_WARMING_UP = 0x0000000B, + PORT_STATUS_POWER_SAVE = 0x0000000C + } spoolss_PortStatus; + + typedef [v1_enum] enum { + PORT_STATUS_TYPE_ERROR = 0x00000001, + PORT_STATUS_TYPE_WARNING = 0x00000002, + PORT_STATUS_TYPE_INFO = 0x00000003 + } spoolss_PortSeverity; + + typedef struct { + spoolss_PortStatus status; + [relative] nstring *status_string; + spoolss_PortSeverity severity; + } spoolss_PortInfo3; + + typedef struct { + [relative] nstring *port_name; + DATA_BLOB monitor_data; /* relative ?? */ + } spoolss_PortInfoFF; + typedef [nodiscriminant,relative_base,public] union { [case(1)] spoolss_PortInfo1 info1; [case(2)] spoolss_PortInfo2 info2; - [case(3)]; /* TODO */ + [case(3)] spoolss_PortInfo3 info3; + [case(0xff)] spoolss_PortInfoFF infoFF; [default]; } spoolss_PortInfo; -- cgit From 5da7fde31e238d49f0811327e4edff19ea2bf1cc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 27 Feb 2009 13:31:02 +0100 Subject: spoolss: fill in spoolss_SetJobInfo1,2,3,4. Guenther --- librpc/idl/spoolss.idl | 79 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 946db7a7bf..f2944b0f39 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -482,9 +482,86 @@ import "misc.idl", "security.idl", "winreg.idl"; [default]; } spoolss_JobInfo; + typedef struct { + uint32 job_id; + [string,charset(UTF16)] uint16 *printer_name; + [string,charset(UTF16)] uint16 *server_name; + [string,charset(UTF16)] uint16 *user_name; + [string,charset(UTF16)] uint16 *document_name; + [string,charset(UTF16)] uint16 *data_type; + [string,charset(UTF16)] uint16 *text_status; + spoolss_JobStatus status; + uint32 priority; + uint32 position; + uint32 total_pages; + uint32 pages_printed; + spoolss_Time submitted; + } spoolss_SetJobInfo1; + + typedef struct { + uint32 job_id; + [string,charset(UTF16)] uint16 *printer_name; + [string,charset(UTF16)] uint16 *server_name; + [string,charset(UTF16)] uint16 *user_name; + [string,charset(UTF16)] uint16 *document_name; + [string,charset(UTF16)] uint16 *notify_name; + [string,charset(UTF16)] uint16 *data_type; + [string,charset(UTF16)] uint16 *print_processor; + [string,charset(UTF16)] uint16 *parameters; + [string,charset(UTF16)] uint16 *driver_name; + spoolss_DeviceMode *devmode; + [string,charset(UTF16)] uint16 *text_status; + security_descriptor *secdesc; + spoolss_JobStatus status; + uint32 priority; + uint32 position; + uint32 start_time; + uint32 until_time; + uint32 total_pages; + uint32 size; + spoolss_Time submitted; + uint32 time; + uint32 pages_printed; + } spoolss_SetJobInfo2; + + typedef struct { + uint32 job_id; + [string,charset(UTF16)] uint16 *printer_name; + [string,charset(UTF16)] uint16 *server_name; + [string,charset(UTF16)] uint16 *user_name; + [string,charset(UTF16)] uint16 *document_name; + [string,charset(UTF16)] uint16 *notify_name; + [string,charset(UTF16)] uint16 *data_type; + [string,charset(UTF16)] uint16 *print_processor; + [string,charset(UTF16)] uint16 *parameters; + [string,charset(UTF16)] uint16 *driver_name; + spoolss_DeviceMode *devmode; + [string,charset(UTF16)] uint16 *text_status; + security_descriptor *secdesc; + spoolss_JobStatus status; + uint32 priority; + uint32 position; + uint32 start_time; + uint32 until_time; + uint32 total_pages; + uint32 size; + spoolss_Time submitted; + uint32 time; + uint32 pages_printed; + uint32 size_high; + } spoolss_SetJobInfo4; + + typedef [public] union { + [case(1)] spoolss_SetJobInfo1 *info1; + [case(2)] spoolss_SetJobInfo2 *info2; + [case(3)] spoolss_JobInfo3 *info3; + [case(4)] spoolss_SetJobInfo4 *info4; + [default]; + } spoolss_SetJobInfo; + typedef struct { uint32 level; - [switch_is(level)] spoolss_JobInfo info; + [switch_is(level)] spoolss_SetJobInfo info; } spoolss_JobInfoContainer; typedef [v1_enum] enum { -- cgit From 0025caa9bd2bf52bf873b38ef4b8e3814579ad17 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 27 Feb 2009 13:33:51 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 1609 +++++++++++++++++++++++++++++++++++++++++- librpc/gen_ndr/ndr_spoolss.h | 10 + librpc/gen_ndr/spoolss.h | 141 +++- 3 files changed, 1754 insertions(+), 6 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 072e9d55d0..31220edc62 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -4335,16 +4335,1357 @@ _PUBLIC_ void ndr_print_spoolss_JobInfo(struct ndr_print *ndr, const char *name, } } +static enum ndr_err_code ndr_push_spoolss_SetJobInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_SetJobInfo1 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->job_id)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->printer_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->server_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->user_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->document_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->data_type)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->text_status)); + NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->status)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->priority)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->total_pages)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->pages_printed)); + NDR_CHECK(ndr_push_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->printer_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->printer_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->printer_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->printer_name, ndr_charset_length(r->printer_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->server_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->server_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->server_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->server_name, ndr_charset_length(r->server_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->user_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->user_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->user_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->user_name, ndr_charset_length(r->user_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->document_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->document_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->document_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->document_name, ndr_charset_length(r->document_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->data_type) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->data_type, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->data_type, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->data_type, ndr_charset_length(r->data_type, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->text_status) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->text_status, ndr_charset_length(r->text_status, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_SetJobInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_SetJobInfo1 *r) +{ + uint32_t _ptr_printer_name; + TALLOC_CTX *_mem_save_printer_name_0; + uint32_t _ptr_server_name; + TALLOC_CTX *_mem_save_server_name_0; + uint32_t _ptr_user_name; + TALLOC_CTX *_mem_save_user_name_0; + uint32_t _ptr_document_name; + TALLOC_CTX *_mem_save_document_name_0; + uint32_t _ptr_data_type; + TALLOC_CTX *_mem_save_data_type_0; + uint32_t _ptr_text_status; + TALLOC_CTX *_mem_save_text_status_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_printer_name)); + if (_ptr_printer_name) { + NDR_PULL_ALLOC(ndr, r->printer_name); + } else { + r->printer_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_server_name)); + if (_ptr_server_name) { + NDR_PULL_ALLOC(ndr, r->server_name); + } else { + r->server_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_user_name)); + if (_ptr_user_name) { + NDR_PULL_ALLOC(ndr, r->user_name); + } else { + r->user_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_document_name)); + if (_ptr_document_name) { + NDR_PULL_ALLOC(ndr, r->document_name); + } else { + r->document_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data_type)); + if (_ptr_data_type) { + NDR_PULL_ALLOC(ndr, r->data_type); + } else { + r->data_type = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_text_status)); + if (_ptr_text_status) { + NDR_PULL_ALLOC(ndr, r->text_status); + } else { + r->text_status = NULL; + } + NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pages_printed)); + NDR_CHECK(ndr_pull_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->printer_name) { + _mem_save_printer_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->printer_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->printer_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->printer_name)); + if (ndr_get_array_length(ndr, &r->printer_name) > ndr_get_array_size(ndr, &r->printer_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->printer_name), ndr_get_array_length(ndr, &r->printer_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->printer_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->printer_name, ndr_get_array_length(ndr, &r->printer_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_printer_name_0, 0); + } + if (r->server_name) { + _mem_save_server_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->server_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->server_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->server_name)); + if (ndr_get_array_length(ndr, &r->server_name) > ndr_get_array_size(ndr, &r->server_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->server_name), ndr_get_array_length(ndr, &r->server_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->server_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->server_name, ndr_get_array_length(ndr, &r->server_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_name_0, 0); + } + if (r->user_name) { + _mem_save_user_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->user_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->user_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->user_name)); + if (ndr_get_array_length(ndr, &r->user_name) > ndr_get_array_size(ndr, &r->user_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->user_name), ndr_get_array_length(ndr, &r->user_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->user_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->user_name, ndr_get_array_length(ndr, &r->user_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_user_name_0, 0); + } + if (r->document_name) { + _mem_save_document_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->document_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->document_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->document_name)); + if (ndr_get_array_length(ndr, &r->document_name) > ndr_get_array_size(ndr, &r->document_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->document_name), ndr_get_array_length(ndr, &r->document_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->document_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->document_name, ndr_get_array_length(ndr, &r->document_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_document_name_0, 0); + } + if (r->data_type) { + _mem_save_data_type_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->data_type, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->data_type)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->data_type)); + if (ndr_get_array_length(ndr, &r->data_type) > ndr_get_array_size(ndr, &r->data_type)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->data_type), ndr_get_array_length(ndr, &r->data_type)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->data_type), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->data_type, ndr_get_array_length(ndr, &r->data_type), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_type_0, 0); + } + if (r->text_status) { + _mem_save_text_status_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->text_status, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->text_status)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->text_status)); + if (ndr_get_array_length(ndr, &r->text_status) > ndr_get_array_size(ndr, &r->text_status)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->text_status), ndr_get_array_length(ndr, &r->text_status)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->text_status), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->text_status, ndr_get_array_length(ndr, &r->text_status), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_text_status_0, 0); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_SetJobInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo1 *r) +{ + ndr_print_struct(ndr, name, "spoolss_SetJobInfo1"); + ndr->depth++; + ndr_print_uint32(ndr, "job_id", r->job_id); + ndr_print_ptr(ndr, "printer_name", r->printer_name); + ndr->depth++; + if (r->printer_name) { + ndr_print_string(ndr, "printer_name", r->printer_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "server_name", r->server_name); + ndr->depth++; + if (r->server_name) { + ndr_print_string(ndr, "server_name", r->server_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "user_name", r->user_name); + ndr->depth++; + if (r->user_name) { + ndr_print_string(ndr, "user_name", r->user_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "document_name", r->document_name); + ndr->depth++; + if (r->document_name) { + ndr_print_string(ndr, "document_name", r->document_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "data_type", r->data_type); + ndr->depth++; + if (r->data_type) { + ndr_print_string(ndr, "data_type", r->data_type); + } + ndr->depth--; + ndr_print_ptr(ndr, "text_status", r->text_status); + ndr->depth++; + if (r->text_status) { + ndr_print_string(ndr, "text_status", r->text_status); + } + ndr->depth--; + ndr_print_spoolss_JobStatus(ndr, "status", r->status); + ndr_print_uint32(ndr, "priority", r->priority); + ndr_print_uint32(ndr, "position", r->position); + ndr_print_uint32(ndr, "total_pages", r->total_pages); + ndr_print_uint32(ndr, "pages_printed", r->pages_printed); + ndr_print_spoolss_Time(ndr, "submitted", &r->submitted); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_spoolss_SetJobInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_SetJobInfo2 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->job_id)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->printer_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->server_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->user_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->document_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->notify_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->data_type)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->print_processor)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->parameters)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->driver_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->devmode)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->text_status)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->secdesc)); + NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->status)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->priority)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->start_time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->until_time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->total_pages)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size)); + NDR_CHECK(ndr_push_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->pages_printed)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->printer_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->printer_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->printer_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->printer_name, ndr_charset_length(r->printer_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->server_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->server_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->server_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->server_name, ndr_charset_length(r->server_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->user_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->user_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->user_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->user_name, ndr_charset_length(r->user_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->document_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->document_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->document_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->document_name, ndr_charset_length(r->document_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->notify_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->notify_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->notify_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->notify_name, ndr_charset_length(r->notify_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->data_type) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->data_type, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->data_type, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->data_type, ndr_charset_length(r->data_type, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->print_processor) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->print_processor, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->print_processor, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->print_processor, ndr_charset_length(r->print_processor, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->parameters) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->parameters, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->parameters, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->parameters, ndr_charset_length(r->parameters, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->driver_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->driver_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->driver_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->driver_name, ndr_charset_length(r->driver_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->devmode) { + NDR_CHECK(ndr_push_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); + } + if (r->text_status) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->text_status, ndr_charset_length(r->text_status, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->secdesc) { + NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_SetJobInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_SetJobInfo2 *r) +{ + uint32_t _ptr_printer_name; + TALLOC_CTX *_mem_save_printer_name_0; + uint32_t _ptr_server_name; + TALLOC_CTX *_mem_save_server_name_0; + uint32_t _ptr_user_name; + TALLOC_CTX *_mem_save_user_name_0; + uint32_t _ptr_document_name; + TALLOC_CTX *_mem_save_document_name_0; + uint32_t _ptr_notify_name; + TALLOC_CTX *_mem_save_notify_name_0; + uint32_t _ptr_data_type; + TALLOC_CTX *_mem_save_data_type_0; + uint32_t _ptr_print_processor; + TALLOC_CTX *_mem_save_print_processor_0; + uint32_t _ptr_parameters; + TALLOC_CTX *_mem_save_parameters_0; + uint32_t _ptr_driver_name; + TALLOC_CTX *_mem_save_driver_name_0; + uint32_t _ptr_devmode; + TALLOC_CTX *_mem_save_devmode_0; + uint32_t _ptr_text_status; + TALLOC_CTX *_mem_save_text_status_0; + uint32_t _ptr_secdesc; + TALLOC_CTX *_mem_save_secdesc_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_printer_name)); + if (_ptr_printer_name) { + NDR_PULL_ALLOC(ndr, r->printer_name); + } else { + r->printer_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_server_name)); + if (_ptr_server_name) { + NDR_PULL_ALLOC(ndr, r->server_name); + } else { + r->server_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_user_name)); + if (_ptr_user_name) { + NDR_PULL_ALLOC(ndr, r->user_name); + } else { + r->user_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_document_name)); + if (_ptr_document_name) { + NDR_PULL_ALLOC(ndr, r->document_name); + } else { + r->document_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_notify_name)); + if (_ptr_notify_name) { + NDR_PULL_ALLOC(ndr, r->notify_name); + } else { + r->notify_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data_type)); + if (_ptr_data_type) { + NDR_PULL_ALLOC(ndr, r->data_type); + } else { + r->data_type = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_print_processor)); + if (_ptr_print_processor) { + NDR_PULL_ALLOC(ndr, r->print_processor); + } else { + r->print_processor = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_parameters)); + if (_ptr_parameters) { + NDR_PULL_ALLOC(ndr, r->parameters); + } else { + r->parameters = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_driver_name)); + if (_ptr_driver_name) { + NDR_PULL_ALLOC(ndr, r->driver_name); + } else { + r->driver_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_devmode)); + if (_ptr_devmode) { + NDR_PULL_ALLOC(ndr, r->devmode); + } else { + r->devmode = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_text_status)); + if (_ptr_text_status) { + NDR_PULL_ALLOC(ndr, r->text_status); + } else { + r->text_status = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_secdesc)); + if (_ptr_secdesc) { + NDR_PULL_ALLOC(ndr, r->secdesc); + } else { + r->secdesc = NULL; + } + NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->start_time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->until_time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pages_printed)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->printer_name) { + _mem_save_printer_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->printer_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->printer_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->printer_name)); + if (ndr_get_array_length(ndr, &r->printer_name) > ndr_get_array_size(ndr, &r->printer_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->printer_name), ndr_get_array_length(ndr, &r->printer_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->printer_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->printer_name, ndr_get_array_length(ndr, &r->printer_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_printer_name_0, 0); + } + if (r->server_name) { + _mem_save_server_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->server_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->server_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->server_name)); + if (ndr_get_array_length(ndr, &r->server_name) > ndr_get_array_size(ndr, &r->server_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->server_name), ndr_get_array_length(ndr, &r->server_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->server_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->server_name, ndr_get_array_length(ndr, &r->server_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_name_0, 0); + } + if (r->user_name) { + _mem_save_user_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->user_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->user_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->user_name)); + if (ndr_get_array_length(ndr, &r->user_name) > ndr_get_array_size(ndr, &r->user_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->user_name), ndr_get_array_length(ndr, &r->user_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->user_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->user_name, ndr_get_array_length(ndr, &r->user_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_user_name_0, 0); + } + if (r->document_name) { + _mem_save_document_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->document_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->document_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->document_name)); + if (ndr_get_array_length(ndr, &r->document_name) > ndr_get_array_size(ndr, &r->document_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->document_name), ndr_get_array_length(ndr, &r->document_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->document_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->document_name, ndr_get_array_length(ndr, &r->document_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_document_name_0, 0); + } + if (r->notify_name) { + _mem_save_notify_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->notify_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->notify_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->notify_name)); + if (ndr_get_array_length(ndr, &r->notify_name) > ndr_get_array_size(ndr, &r->notify_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->notify_name), ndr_get_array_length(ndr, &r->notify_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->notify_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->notify_name, ndr_get_array_length(ndr, &r->notify_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_notify_name_0, 0); + } + if (r->data_type) { + _mem_save_data_type_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->data_type, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->data_type)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->data_type)); + if (ndr_get_array_length(ndr, &r->data_type) > ndr_get_array_size(ndr, &r->data_type)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->data_type), ndr_get_array_length(ndr, &r->data_type)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->data_type), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->data_type, ndr_get_array_length(ndr, &r->data_type), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_type_0, 0); + } + if (r->print_processor) { + _mem_save_print_processor_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->print_processor, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->print_processor)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->print_processor)); + if (ndr_get_array_length(ndr, &r->print_processor) > ndr_get_array_size(ndr, &r->print_processor)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->print_processor), ndr_get_array_length(ndr, &r->print_processor)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->print_processor), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->print_processor, ndr_get_array_length(ndr, &r->print_processor), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_print_processor_0, 0); + } + if (r->parameters) { + _mem_save_parameters_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->parameters, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->parameters)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->parameters)); + if (ndr_get_array_length(ndr, &r->parameters) > ndr_get_array_size(ndr, &r->parameters)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->parameters), ndr_get_array_length(ndr, &r->parameters)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->parameters), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->parameters, ndr_get_array_length(ndr, &r->parameters), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_parameters_0, 0); + } + if (r->driver_name) { + _mem_save_driver_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->driver_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->driver_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->driver_name)); + if (ndr_get_array_length(ndr, &r->driver_name) > ndr_get_array_size(ndr, &r->driver_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->driver_name), ndr_get_array_length(ndr, &r->driver_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->driver_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->driver_name, ndr_get_array_length(ndr, &r->driver_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_driver_name_0, 0); + } + if (r->devmode) { + _mem_save_devmode_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->devmode, 0); + NDR_CHECK(ndr_pull_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_0, 0); + } + if (r->text_status) { + _mem_save_text_status_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->text_status, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->text_status)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->text_status)); + if (ndr_get_array_length(ndr, &r->text_status) > ndr_get_array_size(ndr, &r->text_status)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->text_status), ndr_get_array_length(ndr, &r->text_status)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->text_status), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->text_status, ndr_get_array_length(ndr, &r->text_status), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_text_status_0, 0); + } + if (r->secdesc) { + _mem_save_secdesc_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->secdesc, 0); + NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_secdesc_0, 0); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_SetJobInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo2 *r) +{ + ndr_print_struct(ndr, name, "spoolss_SetJobInfo2"); + ndr->depth++; + ndr_print_uint32(ndr, "job_id", r->job_id); + ndr_print_ptr(ndr, "printer_name", r->printer_name); + ndr->depth++; + if (r->printer_name) { + ndr_print_string(ndr, "printer_name", r->printer_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "server_name", r->server_name); + ndr->depth++; + if (r->server_name) { + ndr_print_string(ndr, "server_name", r->server_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "user_name", r->user_name); + ndr->depth++; + if (r->user_name) { + ndr_print_string(ndr, "user_name", r->user_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "document_name", r->document_name); + ndr->depth++; + if (r->document_name) { + ndr_print_string(ndr, "document_name", r->document_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "notify_name", r->notify_name); + ndr->depth++; + if (r->notify_name) { + ndr_print_string(ndr, "notify_name", r->notify_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "data_type", r->data_type); + ndr->depth++; + if (r->data_type) { + ndr_print_string(ndr, "data_type", r->data_type); + } + ndr->depth--; + ndr_print_ptr(ndr, "print_processor", r->print_processor); + ndr->depth++; + if (r->print_processor) { + ndr_print_string(ndr, "print_processor", r->print_processor); + } + ndr->depth--; + ndr_print_ptr(ndr, "parameters", r->parameters); + ndr->depth++; + if (r->parameters) { + ndr_print_string(ndr, "parameters", r->parameters); + } + ndr->depth--; + ndr_print_ptr(ndr, "driver_name", r->driver_name); + ndr->depth++; + if (r->driver_name) { + ndr_print_string(ndr, "driver_name", r->driver_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "devmode", r->devmode); + ndr->depth++; + if (r->devmode) { + ndr_print_spoolss_DeviceMode(ndr, "devmode", r->devmode); + } + ndr->depth--; + ndr_print_ptr(ndr, "text_status", r->text_status); + ndr->depth++; + if (r->text_status) { + ndr_print_string(ndr, "text_status", r->text_status); + } + ndr->depth--; + ndr_print_ptr(ndr, "secdesc", r->secdesc); + ndr->depth++; + if (r->secdesc) { + ndr_print_security_descriptor(ndr, "secdesc", r->secdesc); + } + ndr->depth--; + ndr_print_spoolss_JobStatus(ndr, "status", r->status); + ndr_print_uint32(ndr, "priority", r->priority); + ndr_print_uint32(ndr, "position", r->position); + ndr_print_uint32(ndr, "start_time", r->start_time); + ndr_print_uint32(ndr, "until_time", r->until_time); + ndr_print_uint32(ndr, "total_pages", r->total_pages); + ndr_print_uint32(ndr, "size", r->size); + ndr_print_spoolss_Time(ndr, "submitted", &r->submitted); + ndr_print_uint32(ndr, "time", r->time); + ndr_print_uint32(ndr, "pages_printed", r->pages_printed); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_spoolss_SetJobInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_SetJobInfo4 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->job_id)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->printer_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->server_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->user_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->document_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->notify_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->data_type)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->print_processor)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->parameters)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->driver_name)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->devmode)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->text_status)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->secdesc)); + NDR_CHECK(ndr_push_spoolss_JobStatus(ndr, NDR_SCALARS, r->status)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->priority)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->position)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->start_time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->until_time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->total_pages)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size)); + NDR_CHECK(ndr_push_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->time)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->pages_printed)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->size_high)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->printer_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->printer_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->printer_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->printer_name, ndr_charset_length(r->printer_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->server_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->server_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->server_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->server_name, ndr_charset_length(r->server_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->user_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->user_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->user_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->user_name, ndr_charset_length(r->user_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->document_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->document_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->document_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->document_name, ndr_charset_length(r->document_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->notify_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->notify_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->notify_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->notify_name, ndr_charset_length(r->notify_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->data_type) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->data_type, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->data_type, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->data_type, ndr_charset_length(r->data_type, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->print_processor) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->print_processor, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->print_processor, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->print_processor, ndr_charset_length(r->print_processor, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->parameters) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->parameters, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->parameters, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->parameters, ndr_charset_length(r->parameters, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->driver_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->driver_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->driver_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->driver_name, ndr_charset_length(r->driver_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->devmode) { + NDR_CHECK(ndr_push_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); + } + if (r->text_status) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->text_status, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->text_status, ndr_charset_length(r->text_status, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + if (r->secdesc) { + NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_SetJobInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_SetJobInfo4 *r) +{ + uint32_t _ptr_printer_name; + TALLOC_CTX *_mem_save_printer_name_0; + uint32_t _ptr_server_name; + TALLOC_CTX *_mem_save_server_name_0; + uint32_t _ptr_user_name; + TALLOC_CTX *_mem_save_user_name_0; + uint32_t _ptr_document_name; + TALLOC_CTX *_mem_save_document_name_0; + uint32_t _ptr_notify_name; + TALLOC_CTX *_mem_save_notify_name_0; + uint32_t _ptr_data_type; + TALLOC_CTX *_mem_save_data_type_0; + uint32_t _ptr_print_processor; + TALLOC_CTX *_mem_save_print_processor_0; + uint32_t _ptr_parameters; + TALLOC_CTX *_mem_save_parameters_0; + uint32_t _ptr_driver_name; + TALLOC_CTX *_mem_save_driver_name_0; + uint32_t _ptr_devmode; + TALLOC_CTX *_mem_save_devmode_0; + uint32_t _ptr_text_status; + TALLOC_CTX *_mem_save_text_status_0; + uint32_t _ptr_secdesc; + TALLOC_CTX *_mem_save_secdesc_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->job_id)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_printer_name)); + if (_ptr_printer_name) { + NDR_PULL_ALLOC(ndr, r->printer_name); + } else { + r->printer_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_server_name)); + if (_ptr_server_name) { + NDR_PULL_ALLOC(ndr, r->server_name); + } else { + r->server_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_user_name)); + if (_ptr_user_name) { + NDR_PULL_ALLOC(ndr, r->user_name); + } else { + r->user_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_document_name)); + if (_ptr_document_name) { + NDR_PULL_ALLOC(ndr, r->document_name); + } else { + r->document_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_notify_name)); + if (_ptr_notify_name) { + NDR_PULL_ALLOC(ndr, r->notify_name); + } else { + r->notify_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data_type)); + if (_ptr_data_type) { + NDR_PULL_ALLOC(ndr, r->data_type); + } else { + r->data_type = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_print_processor)); + if (_ptr_print_processor) { + NDR_PULL_ALLOC(ndr, r->print_processor); + } else { + r->print_processor = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_parameters)); + if (_ptr_parameters) { + NDR_PULL_ALLOC(ndr, r->parameters); + } else { + r->parameters = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_driver_name)); + if (_ptr_driver_name) { + NDR_PULL_ALLOC(ndr, r->driver_name); + } else { + r->driver_name = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_devmode)); + if (_ptr_devmode) { + NDR_PULL_ALLOC(ndr, r->devmode); + } else { + r->devmode = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_text_status)); + if (_ptr_text_status) { + NDR_PULL_ALLOC(ndr, r->text_status); + } else { + r->text_status = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_secdesc)); + if (_ptr_secdesc) { + NDR_PULL_ALLOC(ndr, r->secdesc); + } else { + r->secdesc = NULL; + } + NDR_CHECK(ndr_pull_spoolss_JobStatus(ndr, NDR_SCALARS, &r->status)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->priority)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->position)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->start_time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->until_time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->total_pages)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_spoolss_Time(ndr, NDR_SCALARS, &r->submitted)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->time)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pages_printed)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size_high)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->printer_name) { + _mem_save_printer_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->printer_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->printer_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->printer_name)); + if (ndr_get_array_length(ndr, &r->printer_name) > ndr_get_array_size(ndr, &r->printer_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->printer_name), ndr_get_array_length(ndr, &r->printer_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->printer_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->printer_name, ndr_get_array_length(ndr, &r->printer_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_printer_name_0, 0); + } + if (r->server_name) { + _mem_save_server_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->server_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->server_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->server_name)); + if (ndr_get_array_length(ndr, &r->server_name) > ndr_get_array_size(ndr, &r->server_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->server_name), ndr_get_array_length(ndr, &r->server_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->server_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->server_name, ndr_get_array_length(ndr, &r->server_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_name_0, 0); + } + if (r->user_name) { + _mem_save_user_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->user_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->user_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->user_name)); + if (ndr_get_array_length(ndr, &r->user_name) > ndr_get_array_size(ndr, &r->user_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->user_name), ndr_get_array_length(ndr, &r->user_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->user_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->user_name, ndr_get_array_length(ndr, &r->user_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_user_name_0, 0); + } + if (r->document_name) { + _mem_save_document_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->document_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->document_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->document_name)); + if (ndr_get_array_length(ndr, &r->document_name) > ndr_get_array_size(ndr, &r->document_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->document_name), ndr_get_array_length(ndr, &r->document_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->document_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->document_name, ndr_get_array_length(ndr, &r->document_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_document_name_0, 0); + } + if (r->notify_name) { + _mem_save_notify_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->notify_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->notify_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->notify_name)); + if (ndr_get_array_length(ndr, &r->notify_name) > ndr_get_array_size(ndr, &r->notify_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->notify_name), ndr_get_array_length(ndr, &r->notify_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->notify_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->notify_name, ndr_get_array_length(ndr, &r->notify_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_notify_name_0, 0); + } + if (r->data_type) { + _mem_save_data_type_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->data_type, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->data_type)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->data_type)); + if (ndr_get_array_length(ndr, &r->data_type) > ndr_get_array_size(ndr, &r->data_type)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->data_type), ndr_get_array_length(ndr, &r->data_type)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->data_type), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->data_type, ndr_get_array_length(ndr, &r->data_type), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_type_0, 0); + } + if (r->print_processor) { + _mem_save_print_processor_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->print_processor, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->print_processor)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->print_processor)); + if (ndr_get_array_length(ndr, &r->print_processor) > ndr_get_array_size(ndr, &r->print_processor)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->print_processor), ndr_get_array_length(ndr, &r->print_processor)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->print_processor), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->print_processor, ndr_get_array_length(ndr, &r->print_processor), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_print_processor_0, 0); + } + if (r->parameters) { + _mem_save_parameters_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->parameters, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->parameters)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->parameters)); + if (ndr_get_array_length(ndr, &r->parameters) > ndr_get_array_size(ndr, &r->parameters)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->parameters), ndr_get_array_length(ndr, &r->parameters)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->parameters), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->parameters, ndr_get_array_length(ndr, &r->parameters), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_parameters_0, 0); + } + if (r->driver_name) { + _mem_save_driver_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->driver_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->driver_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->driver_name)); + if (ndr_get_array_length(ndr, &r->driver_name) > ndr_get_array_size(ndr, &r->driver_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->driver_name), ndr_get_array_length(ndr, &r->driver_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->driver_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->driver_name, ndr_get_array_length(ndr, &r->driver_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_driver_name_0, 0); + } + if (r->devmode) { + _mem_save_devmode_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->devmode, 0); + NDR_CHECK(ndr_pull_spoolss_DeviceMode(ndr, NDR_SCALARS, r->devmode)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_0, 0); + } + if (r->text_status) { + _mem_save_text_status_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->text_status, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->text_status)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->text_status)); + if (ndr_get_array_length(ndr, &r->text_status) > ndr_get_array_size(ndr, &r->text_status)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->text_status), ndr_get_array_length(ndr, &r->text_status)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->text_status), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->text_status, ndr_get_array_length(ndr, &r->text_status), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_text_status_0, 0); + } + if (r->secdesc) { + _mem_save_secdesc_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->secdesc, 0); + NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_secdesc_0, 0); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_SetJobInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo4 *r) +{ + ndr_print_struct(ndr, name, "spoolss_SetJobInfo4"); + ndr->depth++; + ndr_print_uint32(ndr, "job_id", r->job_id); + ndr_print_ptr(ndr, "printer_name", r->printer_name); + ndr->depth++; + if (r->printer_name) { + ndr_print_string(ndr, "printer_name", r->printer_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "server_name", r->server_name); + ndr->depth++; + if (r->server_name) { + ndr_print_string(ndr, "server_name", r->server_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "user_name", r->user_name); + ndr->depth++; + if (r->user_name) { + ndr_print_string(ndr, "user_name", r->user_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "document_name", r->document_name); + ndr->depth++; + if (r->document_name) { + ndr_print_string(ndr, "document_name", r->document_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "notify_name", r->notify_name); + ndr->depth++; + if (r->notify_name) { + ndr_print_string(ndr, "notify_name", r->notify_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "data_type", r->data_type); + ndr->depth++; + if (r->data_type) { + ndr_print_string(ndr, "data_type", r->data_type); + } + ndr->depth--; + ndr_print_ptr(ndr, "print_processor", r->print_processor); + ndr->depth++; + if (r->print_processor) { + ndr_print_string(ndr, "print_processor", r->print_processor); + } + ndr->depth--; + ndr_print_ptr(ndr, "parameters", r->parameters); + ndr->depth++; + if (r->parameters) { + ndr_print_string(ndr, "parameters", r->parameters); + } + ndr->depth--; + ndr_print_ptr(ndr, "driver_name", r->driver_name); + ndr->depth++; + if (r->driver_name) { + ndr_print_string(ndr, "driver_name", r->driver_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "devmode", r->devmode); + ndr->depth++; + if (r->devmode) { + ndr_print_spoolss_DeviceMode(ndr, "devmode", r->devmode); + } + ndr->depth--; + ndr_print_ptr(ndr, "text_status", r->text_status); + ndr->depth++; + if (r->text_status) { + ndr_print_string(ndr, "text_status", r->text_status); + } + ndr->depth--; + ndr_print_ptr(ndr, "secdesc", r->secdesc); + ndr->depth++; + if (r->secdesc) { + ndr_print_security_descriptor(ndr, "secdesc", r->secdesc); + } + ndr->depth--; + ndr_print_spoolss_JobStatus(ndr, "status", r->status); + ndr_print_uint32(ndr, "priority", r->priority); + ndr_print_uint32(ndr, "position", r->position); + ndr_print_uint32(ndr, "start_time", r->start_time); + ndr_print_uint32(ndr, "until_time", r->until_time); + ndr_print_uint32(ndr, "total_pages", r->total_pages); + ndr_print_uint32(ndr, "size", r->size); + ndr_print_spoolss_Time(ndr, "submitted", &r->submitted); + ndr_print_uint32(ndr, "time", r->time); + ndr_print_uint32(ndr, "pages_printed", r->pages_printed); + ndr_print_uint32(ndr, "size_high", r->size_high); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_SetJobInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_SetJobInfo *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, level)); + switch (level) { + case 1: { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->info1)); + break; } + + case 2: { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->info2)); + break; } + + case 3: { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->info3)); + break; } + + case 4: { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->info4)); + break; } + + default: { + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case 1: + if (r->info1) { + NDR_CHECK(ndr_push_spoolss_SetJobInfo1(ndr, NDR_SCALARS|NDR_BUFFERS, r->info1)); + } + break; + + case 2: + if (r->info2) { + NDR_CHECK(ndr_push_spoolss_SetJobInfo2(ndr, NDR_SCALARS|NDR_BUFFERS, r->info2)); + } + break; + + case 3: + if (r->info3) { + NDR_CHECK(ndr_push_spoolss_JobInfo3(ndr, NDR_SCALARS, r->info3)); + } + break; + + case 4: + if (r->info4) { + NDR_CHECK(ndr_push_spoolss_SetJobInfo4(ndr, NDR_SCALARS|NDR_BUFFERS, r->info4)); + } + break; + + default: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_SetJobInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_SetJobInfo *r) +{ + int level; + uint32_t _level; + TALLOC_CTX *_mem_save_info1_0; + TALLOC_CTX *_mem_save_info2_0; + TALLOC_CTX *_mem_save_info3_0; + TALLOC_CTX *_mem_save_info4_0; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level)); + if (_level != level) { + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u for r", _level); + } + switch (level) { + case 1: { + uint32_t _ptr_info1; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info1)); + if (_ptr_info1) { + NDR_PULL_ALLOC(ndr, r->info1); + } else { + r->info1 = NULL; + } + break; } + + case 2: { + uint32_t _ptr_info2; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info2)); + if (_ptr_info2) { + NDR_PULL_ALLOC(ndr, r->info2); + } else { + r->info2 = NULL; + } + break; } + + case 3: { + uint32_t _ptr_info3; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info3)); + if (_ptr_info3) { + NDR_PULL_ALLOC(ndr, r->info3); + } else { + r->info3 = NULL; + } + break; } + + case 4: { + uint32_t _ptr_info4; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info4)); + if (_ptr_info4) { + NDR_PULL_ALLOC(ndr, r->info4); + } else { + r->info4 = NULL; + } + break; } + + default: { + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case 1: + if (r->info1) { + _mem_save_info1_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info1, 0); + NDR_CHECK(ndr_pull_spoolss_SetJobInfo1(ndr, NDR_SCALARS|NDR_BUFFERS, r->info1)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info1_0, 0); + } + break; + + case 2: + if (r->info2) { + _mem_save_info2_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info2, 0); + NDR_CHECK(ndr_pull_spoolss_SetJobInfo2(ndr, NDR_SCALARS|NDR_BUFFERS, r->info2)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info2_0, 0); + } + break; + + case 3: + if (r->info3) { + _mem_save_info3_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info3, 0); + NDR_CHECK(ndr_pull_spoolss_JobInfo3(ndr, NDR_SCALARS, r->info3)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info3_0, 0); + } + break; + + case 4: + if (r->info4) { + _mem_save_info4_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info4, 0); + NDR_CHECK(ndr_pull_spoolss_SetJobInfo4(ndr, NDR_SCALARS|NDR_BUFFERS, r->info4)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info4_0, 0); + } + break; + + default: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_SetJobInfo(struct ndr_print *ndr, const char *name, const union spoolss_SetJobInfo *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "spoolss_SetJobInfo"); + switch (level) { + case 1: + ndr_print_ptr(ndr, "info1", r->info1); + ndr->depth++; + if (r->info1) { + ndr_print_spoolss_SetJobInfo1(ndr, "info1", r->info1); + } + ndr->depth--; + break; + + case 2: + ndr_print_ptr(ndr, "info2", r->info2); + ndr->depth++; + if (r->info2) { + ndr_print_spoolss_SetJobInfo2(ndr, "info2", r->info2); + } + ndr->depth--; + break; + + case 3: + ndr_print_ptr(ndr, "info3", r->info3); + ndr->depth++; + if (r->info3) { + ndr_print_spoolss_JobInfo3(ndr, "info3", r->info3); + } + ndr->depth--; + break; + + case 4: + ndr_print_ptr(ndr, "info4", r->info4); + ndr->depth++; + if (r->info4) { + ndr_print_spoolss_SetJobInfo4(ndr, "info4", r->info4); + } + ndr->depth--; + break; + + default: + break; + + } +} + static enum ndr_err_code ndr_push_spoolss_JobInfoContainer(struct ndr_push *ndr, int ndr_flags, const struct spoolss_JobInfoContainer *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->level)); NDR_CHECK(ndr_push_set_switch_value(ndr, &r->info, r->level)); - NDR_CHECK(ndr_push_spoolss_JobInfo(ndr, NDR_SCALARS, &r->info)); + NDR_CHECK(ndr_push_spoolss_SetJobInfo(ndr, NDR_SCALARS, &r->info)); } if (ndr_flags & NDR_BUFFERS) { - NDR_CHECK(ndr_push_spoolss_JobInfo(ndr, NDR_BUFFERS, &r->info)); + NDR_CHECK(ndr_push_spoolss_SetJobInfo(ndr, NDR_BUFFERS, &r->info)); } return NDR_ERR_SUCCESS; } @@ -4355,10 +5696,10 @@ static enum ndr_err_code ndr_pull_spoolss_JobInfoContainer(struct ndr_pull *ndr, NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->level)); NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->info, r->level)); - NDR_CHECK(ndr_pull_spoolss_JobInfo(ndr, NDR_SCALARS, &r->info)); + NDR_CHECK(ndr_pull_spoolss_SetJobInfo(ndr, NDR_SCALARS, &r->info)); } if (ndr_flags & NDR_BUFFERS) { - NDR_CHECK(ndr_pull_spoolss_JobInfo(ndr, NDR_BUFFERS, &r->info)); + NDR_CHECK(ndr_pull_spoolss_SetJobInfo(ndr, NDR_BUFFERS, &r->info)); } return NDR_ERR_SUCCESS; } @@ -4369,7 +5710,7 @@ _PUBLIC_ void ndr_print_spoolss_JobInfoContainer(struct ndr_print *ndr, const ch ndr->depth++; ndr_print_uint32(ndr, "level", r->level); ndr_print_set_switch_value(ndr, &r->info, r->level); - ndr_print_spoolss_JobInfo(ndr, "info", &r->info); + ndr_print_spoolss_SetJobInfo(ndr, "info", &r->info); ndr->depth--; } @@ -14640,6 +15981,231 @@ _PUBLIC_ void ndr_print_spoolss_PortInfo2(struct ndr_print *ndr, const char *nam ndr->depth--; } +static enum ndr_err_code ndr_push_spoolss_PortStatus(struct ndr_push *ndr, int ndr_flags, enum spoolss_PortStatus r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_PortStatus(struct ndr_pull *ndr, int ndr_flags, enum spoolss_PortStatus *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_PortStatus(struct ndr_print *ndr, const char *name, enum spoolss_PortStatus r) +{ + const char *val = NULL; + + switch (r) { + case PORT_STATUS_CLEAR: val = "PORT_STATUS_CLEAR"; break; + case PORT_STATUS_OFFLINE: val = "PORT_STATUS_OFFLINE"; break; + case PORT_STATUS_PAPER_JAM: val = "PORT_STATUS_PAPER_JAM"; break; + case PORT_STATUS_PAPER_OUT: val = "PORT_STATUS_PAPER_OUT"; break; + case PORT_STATUS_OUTPUT_BIN_FULL: val = "PORT_STATUS_OUTPUT_BIN_FULL"; break; + case PORT_STATUS_PAPER_PROBLEM: val = "PORT_STATUS_PAPER_PROBLEM"; break; + case PORT_STATUS_NO_TONER: val = "PORT_STATUS_NO_TONER"; break; + case PORT_STATUS_DOOR_OPEN: val = "PORT_STATUS_DOOR_OPEN"; break; + case PORT_STATUS_USER_INTERVENTION: val = "PORT_STATUS_USER_INTERVENTION"; break; + case PORT_STATUS_OUT_OF_MEMORY: val = "PORT_STATUS_OUT_OF_MEMORY"; break; + case PORT_STATUS_TONER_LOW: val = "PORT_STATUS_TONER_LOW"; break; + case PORT_STATUS_WARMING_UP: val = "PORT_STATUS_WARMING_UP"; break; + case PORT_STATUS_POWER_SAVE: val = "PORT_STATUS_POWER_SAVE"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +static enum ndr_err_code ndr_push_spoolss_PortSeverity(struct ndr_push *ndr, int ndr_flags, enum spoolss_PortSeverity r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_PortSeverity(struct ndr_pull *ndr, int ndr_flags, enum spoolss_PortSeverity *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_PortSeverity(struct ndr_print *ndr, const char *name, enum spoolss_PortSeverity r) +{ + const char *val = NULL; + + switch (r) { + case PORT_STATUS_TYPE_ERROR: val = "PORT_STATUS_TYPE_ERROR"; break; + case PORT_STATUS_TYPE_WARNING: val = "PORT_STATUS_TYPE_WARNING"; break; + case PORT_STATUS_TYPE_INFO: val = "PORT_STATUS_TYPE_INFO"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +static enum ndr_err_code ndr_push_spoolss_PortInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfo3 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_spoolss_PortStatus(ndr, NDR_SCALARS, r->status)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->status_string)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_spoolss_PortSeverity(ndr, NDR_SCALARS, r->severity)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->status_string) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->status_string)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->status_string)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_PortInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfo3 *r) +{ + uint32_t _ptr_status_string; + TALLOC_CTX *_mem_save_status_string_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_spoolss_PortStatus(ndr, NDR_SCALARS, &r->status)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_status_string)); + if (_ptr_status_string) { + NDR_PULL_ALLOC(ndr, r->status_string); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->status_string, _ptr_status_string)); + } else { + r->status_string = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_spoolss_PortSeverity(ndr, NDR_SCALARS, &r->severity)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->status_string) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->status_string)); + _mem_save_status_string_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->status_string, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->status_string)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_status_string_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_PortInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfo3 *r) +{ + ndr_print_struct(ndr, name, "spoolss_PortInfo3"); + ndr->depth++; + ndr_print_spoolss_PortStatus(ndr, "status", r->status); + ndr_print_ptr(ndr, "status_string", r->status_string); + ndr->depth++; + if (r->status_string) { + ndr_print_string(ndr, "status_string", r->status_string); + } + ndr->depth--; + ndr_print_spoolss_PortSeverity(ndr, "severity", r->severity); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_spoolss_PortInfoFF(struct ndr_push *ndr, int ndr_flags, const struct spoolss_PortInfoFF *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->port_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->monitor_data)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->port_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->port_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->port_name)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_PortInfoFF(struct ndr_pull *ndr, int ndr_flags, struct spoolss_PortInfoFF *r) +{ + uint32_t _ptr_port_name; + TALLOC_CTX *_mem_save_port_name_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_port_name)); + if (_ptr_port_name) { + NDR_PULL_ALLOC(ndr, r->port_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->port_name, _ptr_port_name)); + } else { + r->port_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->monitor_data)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->port_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->port_name)); + _mem_save_port_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->port_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->port_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_port_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_PortInfoFF(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfoFF *r) +{ + ndr_print_struct(ndr, name, "spoolss_PortInfoFF"); + ndr->depth++; + ndr_print_ptr(ndr, "port_name", r->port_name); + ndr->depth++; + if (r->port_name) { + ndr_print_string(ndr, "port_name", r->port_name); + } + ndr->depth--; + ndr_print_DATA_BLOB(ndr, "monitor_data", r->monitor_data); + ndr->depth--; +} + _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PortInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PortInfo *r) { uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr); @@ -14659,6 +16225,15 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PortInfo(struct ndr_push *ndr, int n break; } case 3: { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_PortInfo3(ndr, NDR_SCALARS, &r->info3)); + break; } + + case 0xff: { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_PortInfoFF(ndr, NDR_SCALARS, &r->infoFF)); break; } default: { @@ -14679,6 +16254,11 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_PortInfo(struct ndr_push *ndr, int n break; case 3: + NDR_CHECK(ndr_push_spoolss_PortInfo3(ndr, NDR_BUFFERS, &r->info3)); + break; + + case 0xff: + NDR_CHECK(ndr_push_spoolss_PortInfoFF(ndr, NDR_BUFFERS, &r->infoFF)); break; default: @@ -14710,6 +16290,15 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PortInfo(struct ndr_pull *ndr, int n break; } case 3: { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_PortInfo3(ndr, NDR_SCALARS, &r->info3)); + break; } + + case 0xff: { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_PortInfoFF(ndr, NDR_SCALARS, &r->infoFF)); break; } default: { @@ -14729,6 +16318,11 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_PortInfo(struct ndr_pull *ndr, int n break; case 3: + NDR_CHECK(ndr_pull_spoolss_PortInfo3(ndr, NDR_BUFFERS, &r->info3)); + break; + + case 0xff: + NDR_CHECK(ndr_pull_spoolss_PortInfoFF(ndr, NDR_BUFFERS, &r->infoFF)); break; default: @@ -14755,6 +16349,11 @@ _PUBLIC_ void ndr_print_spoolss_PortInfo(struct ndr_print *ndr, const char *name break; case 3: + ndr_print_spoolss_PortInfo3(ndr, "info3", &r->info3); + break; + + case 0xff: + ndr_print_spoolss_PortInfoFF(ndr, "infoFF", &r->infoFF); break; default: diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index f18c0fd77e..84ab8b7d05 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -243,6 +243,12 @@ void ndr_print_spoolss_JobInfo4(struct ndr_print *ndr, const char *name, const s enum ndr_err_code ndr_push_spoolss_JobInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_JobInfo *r); enum ndr_err_code ndr_pull_spoolss_JobInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_JobInfo *r); void ndr_print_spoolss_JobInfo(struct ndr_print *ndr, const char *name, const union spoolss_JobInfo *r); +void ndr_print_spoolss_SetJobInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo1 *r); +void ndr_print_spoolss_SetJobInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo2 *r); +void ndr_print_spoolss_SetJobInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_SetJobInfo4 *r); +enum ndr_err_code ndr_push_spoolss_SetJobInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_SetJobInfo *r); +enum ndr_err_code ndr_pull_spoolss_SetJobInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_SetJobInfo *r); +void ndr_print_spoolss_SetJobInfo(struct ndr_print *ndr, const char *name, const union spoolss_SetJobInfo *r); void ndr_print_spoolss_JobInfoContainer(struct ndr_print *ndr, const char *name, const struct spoolss_JobInfoContainer *r); void ndr_print_spoolss_JobControl(struct ndr_print *ndr, const char *name, enum spoolss_JobControl r); void ndr_print_spoolss_PrinterControl(struct ndr_print *ndr, const char *name, enum spoolss_PrinterControl r); @@ -360,6 +366,10 @@ void ndr_print_spoolss_AddFormInfo(struct ndr_print *ndr, const char *name, cons void ndr_print_spoolss_PortInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfo1 *r); void ndr_print_spoolss_PortType(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_spoolss_PortInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfo2 *r); +void ndr_print_spoolss_PortStatus(struct ndr_print *ndr, const char *name, enum spoolss_PortStatus r); +void ndr_print_spoolss_PortSeverity(struct ndr_print *ndr, const char *name, enum spoolss_PortSeverity r); +void ndr_print_spoolss_PortInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfo3 *r); +void ndr_print_spoolss_PortInfoFF(struct ndr_print *ndr, const char *name, const struct spoolss_PortInfoFF *r); enum ndr_err_code ndr_push_spoolss_PortInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_PortInfo *r); enum ndr_err_code ndr_pull_spoolss_PortInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_PortInfo *r); void ndr_print_spoolss_PortInfo(struct ndr_print *ndr, const char *name, const union spoolss_PortInfo *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 3675b88225..b66e4ab2a8 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -470,9 +470,85 @@ union spoolss_JobInfo { struct spoolss_JobInfo4 info4;/* [case(4)] */ }/* [relative_base,nodiscriminant,public] */; +struct spoolss_SetJobInfo1 { + uint32_t job_id; + const char *printer_name;/* [unique,charset(UTF16)] */ + const char *server_name;/* [unique,charset(UTF16)] */ + const char *user_name;/* [unique,charset(UTF16)] */ + const char *document_name;/* [unique,charset(UTF16)] */ + const char *data_type;/* [unique,charset(UTF16)] */ + const char *text_status;/* [unique,charset(UTF16)] */ + uint32_t status; + uint32_t priority; + uint32_t position; + uint32_t total_pages; + uint32_t pages_printed; + struct spoolss_Time submitted; +}; + +struct spoolss_SetJobInfo2 { + uint32_t job_id; + const char *printer_name;/* [unique,charset(UTF16)] */ + const char *server_name;/* [unique,charset(UTF16)] */ + const char *user_name;/* [unique,charset(UTF16)] */ + const char *document_name;/* [unique,charset(UTF16)] */ + const char *notify_name;/* [unique,charset(UTF16)] */ + const char *data_type;/* [unique,charset(UTF16)] */ + const char *print_processor;/* [unique,charset(UTF16)] */ + const char *parameters;/* [unique,charset(UTF16)] */ + const char *driver_name;/* [unique,charset(UTF16)] */ + struct spoolss_DeviceMode *devmode;/* [unique] */ + const char *text_status;/* [unique,charset(UTF16)] */ + struct security_descriptor *secdesc;/* [unique] */ + uint32_t status; + uint32_t priority; + uint32_t position; + uint32_t start_time; + uint32_t until_time; + uint32_t total_pages; + uint32_t size; + struct spoolss_Time submitted; + uint32_t time; + uint32_t pages_printed; +}; + +struct spoolss_SetJobInfo4 { + uint32_t job_id; + const char *printer_name;/* [unique,charset(UTF16)] */ + const char *server_name;/* [unique,charset(UTF16)] */ + const char *user_name;/* [unique,charset(UTF16)] */ + const char *document_name;/* [unique,charset(UTF16)] */ + const char *notify_name;/* [unique,charset(UTF16)] */ + const char *data_type;/* [unique,charset(UTF16)] */ + const char *print_processor;/* [unique,charset(UTF16)] */ + const char *parameters;/* [unique,charset(UTF16)] */ + const char *driver_name;/* [unique,charset(UTF16)] */ + struct spoolss_DeviceMode *devmode;/* [unique] */ + const char *text_status;/* [unique,charset(UTF16)] */ + struct security_descriptor *secdesc;/* [unique] */ + uint32_t status; + uint32_t priority; + uint32_t position; + uint32_t start_time; + uint32_t until_time; + uint32_t total_pages; + uint32_t size; + struct spoolss_Time submitted; + uint32_t time; + uint32_t pages_printed; + uint32_t size_high; +}; + +union spoolss_SetJobInfo { + struct spoolss_SetJobInfo1 *info1;/* [unique,case] */ + struct spoolss_SetJobInfo2 *info2;/* [unique,case(2)] */ + struct spoolss_JobInfo3 *info3;/* [unique,case(3)] */ + struct spoolss_SetJobInfo4 *info4;/* [unique,case(4)] */ +}/* [public] */; + struct spoolss_JobInfoContainer { uint32_t level; - union spoolss_JobInfo info;/* [switch_is(level)] */ + union spoolss_SetJobInfo info;/* [switch_is(level)] */ }; enum spoolss_JobControl @@ -1108,9 +1184,72 @@ struct spoolss_PortInfo2 { uint32_t reserved; }; +enum spoolss_PortStatus +#ifndef USE_UINT_ENUMS + { + PORT_STATUS_CLEAR=0x00000000, + PORT_STATUS_OFFLINE=0x00000001, + PORT_STATUS_PAPER_JAM=0x00000002, + PORT_STATUS_PAPER_OUT=0x00000003, + PORT_STATUS_OUTPUT_BIN_FULL=0x00000004, + PORT_STATUS_PAPER_PROBLEM=0x00000005, + PORT_STATUS_NO_TONER=0x00000006, + PORT_STATUS_DOOR_OPEN=0x00000007, + PORT_STATUS_USER_INTERVENTION=0x00000008, + PORT_STATUS_OUT_OF_MEMORY=0x00000009, + PORT_STATUS_TONER_LOW=0x0000000A, + PORT_STATUS_WARMING_UP=0x0000000B, + PORT_STATUS_POWER_SAVE=0x0000000C +} +#else + { __donnot_use_enum_spoolss_PortStatus=0x7FFFFFFF} +#define PORT_STATUS_CLEAR ( 0x00000000 ) +#define PORT_STATUS_OFFLINE ( 0x00000001 ) +#define PORT_STATUS_PAPER_JAM ( 0x00000002 ) +#define PORT_STATUS_PAPER_OUT ( 0x00000003 ) +#define PORT_STATUS_OUTPUT_BIN_FULL ( 0x00000004 ) +#define PORT_STATUS_PAPER_PROBLEM ( 0x00000005 ) +#define PORT_STATUS_NO_TONER ( 0x00000006 ) +#define PORT_STATUS_DOOR_OPEN ( 0x00000007 ) +#define PORT_STATUS_USER_INTERVENTION ( 0x00000008 ) +#define PORT_STATUS_OUT_OF_MEMORY ( 0x00000009 ) +#define PORT_STATUS_TONER_LOW ( 0x0000000A ) +#define PORT_STATUS_WARMING_UP ( 0x0000000B ) +#define PORT_STATUS_POWER_SAVE ( 0x0000000C ) +#endif +; + +enum spoolss_PortSeverity +#ifndef USE_UINT_ENUMS + { + PORT_STATUS_TYPE_ERROR=0x00000001, + PORT_STATUS_TYPE_WARNING=0x00000002, + PORT_STATUS_TYPE_INFO=0x00000003 +} +#else + { __donnot_use_enum_spoolss_PortSeverity=0x7FFFFFFF} +#define PORT_STATUS_TYPE_ERROR ( 0x00000001 ) +#define PORT_STATUS_TYPE_WARNING ( 0x00000002 ) +#define PORT_STATUS_TYPE_INFO ( 0x00000003 ) +#endif +; + +struct spoolss_PortInfo3 { + enum spoolss_PortStatus status; + const char * status_string;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + enum spoolss_PortSeverity severity; +}; + +struct spoolss_PortInfoFF { + const char * port_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + DATA_BLOB monitor_data; +}; + union spoolss_PortInfo { struct spoolss_PortInfo1 info1;/* [case] */ struct spoolss_PortInfo2 info2;/* [case(2)] */ + struct spoolss_PortInfo3 info3;/* [case(3)] */ + struct spoolss_PortInfoFF infoFF;/* [case(0xff)] */ }/* [relative_base,nodiscriminant,public] */; struct spoolss_MonitorInfo1 { -- cgit From a54520fd4d357eadccb5e101a5b74b50e6d7ab25 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Thu, 26 Feb 2009 17:44:33 +0800 Subject: Initialize the id_map status in idmap_ldap to avoid surprise --- source3/winbindd/idmap_ldap.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c index c86a5023d0..7224589076 100644 --- a/source3/winbindd/idmap_ldap.c +++ b/source3/winbindd/idmap_ldap.c @@ -935,6 +935,10 @@ static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom, multi = True; } + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + again: if (multi) { @@ -1156,6 +1160,10 @@ static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom, multi = True; } + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + again: if (multi) { -- cgit From 9569d979de43970399f33645323e9091338084f6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Feb 2009 20:57:49 -0800 Subject: And the prize for the most pain caused in the build farm for a simple typo goes to..... Tim Prouty !!!! Sorry Tim, nice test but you made a typo in passing in the size of an array so we were reading uninitialized memory :-). That took far longer than it should have to track down... (%$&#ing build system....). The build farm should now slowly go back to normal. Jeremy. --- source4/torture/raw/streams.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c index bf87bd224f..d0d21ccc06 100644 --- a/source4/torture/raw/streams.c +++ b/source4/torture/raw/streams.c @@ -1454,7 +1454,7 @@ static bool test_stream_create_disposition(struct torture_context *tctx, status = smb_raw_open(cli->tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); smbcli_close(cli->tree, io.ntcreatex.out.file.fnum); - if (!check_stream_list(cli, fname, 2, &default_stream_name)) { + if (!check_stream_list(cli, fname, 1, &default_stream_name)) { goto done; } -- cgit From ddd3da8ab7b82a59b84338fb4814981d5ae2f8e4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Feb 2009 12:19:24 +0100 Subject: Simplify async_connect_send slightly --- lib/async_req/async_sock.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 40e7bca4c8..1f48697f26 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -268,8 +268,8 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, state->result = connect(fd, address, address_len); if (state->result == 0) { - errno = 0; - goto post_errno; + tevent_req_done(result); + goto done; } /** @@ -284,25 +284,22 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, errno == EISCONN || #endif errno == EAGAIN || errno == EINTR)) { + state->sys_errno = errno; goto post_errno; } fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, async_connect_connected, result); if (fde == NULL) { - errno = ENOMEM; + state->sys_errno = ENOMEM; goto post_errno; } return result; post_errno: - state->sys_errno = errno; + tevent_req_error(result, state->sys_errno); + done: fcntl(fd, F_SETFL, state->old_sockflags); - if (state->sys_errno == 0) { - tevent_req_done(result); - } else { - tevent_req_error(result, state->sys_errno); - } return tevent_req_post(result, ev); } -- cgit From 5686a6d91a2e1669dd9d00ba1faf493b0bb5ee90 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Feb 2009 12:20:56 +0100 Subject: Fix async reading winbindd_response --- source3/lib/wb_reqtrans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index a5adf8f108..65906dcb91 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -288,7 +288,7 @@ static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data) return -1; } } - return resp->length - 4; + return resp->length - buflen; } static void wb_resp_read_done(struct tevent_req *subreq) -- cgit From 7b9381fb4f0db661a32ab884fb621cb6806ecd32 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 28 Feb 2009 13:14:23 -0800 Subject: Fix bug #6082 - smbd_gpfs_getacl failed: Windows client canĀ“t rename or delete file (directory fix). Jeremy. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source3/smbd/open.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index a42705adb6..569c260319 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2457,6 +2457,25 @@ static NTSTATUS open_directory(connection_struct *conn, fname, access_mask, &access_granted); + + /* Were we trying to do a directory open + * for delete and didn't get DELETE + * access (only) ? Check if the + * directory allows DELETE_CHILD. + * See here: + * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx + * for details. */ + + if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) && + (access_mask & DELETE_ACCESS) && + (access_granted == DELETE_ACCESS) && + can_delete_file_in_directory(conn, fname))) { + DEBUG(10,("open_directory: overrode ACCESS_DENIED " + "on directory %s\n", + fname )); + status = NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("open_directory: check_open_rights on " "file %s failed with %s\n", -- cgit From e6ec32f3acbf626f7cf52fc516f9b496d4e1d6f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 1 Mar 2009 04:59:07 +0100 Subject: Eliminate two duplicate SEC_ACE_TYPE constants already provided by security.idl. --- source3/include/rpc_secdes.h | 3 --- source3/lib/display_sec.c | 8 ++++---- source3/libads/disp_sec.c | 8 ++++---- source3/libgpo/gpo_sec.c | 4 ++-- source3/rpc_parse/parse_sec.c | 4 ++-- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index a1cfad9003..4bf0d9cb9d 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -39,9 +39,6 @@ #define SEC_RIGHTS_RESET_PASSWD SEC_RIGHTS_EXTENDED #define SEC_RIGHTS_FULL_CTRL 0xf01ff -#define SEC_ACE_OBJECT_PRESENT 0x00000001 /* thanks for Jim McDonough */ -#define SEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002 - /* * New Windows 2000 bits. */ diff --git a/source3/lib/display_sec.c b/source3/lib/display_sec.c index 636639c11d..fe1ae77edd 100644 --- a/source3/lib/display_sec.c +++ b/source3/lib/display_sec.c @@ -155,13 +155,13 @@ void display_sec_ace_flags(uint8_t flags) ****************************************************************************/ static void disp_sec_ace_object(struct security_ace_object *object) { - if (object->flags & SEC_ACE_OBJECT_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_PRESENT\n"); + if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n"); printf("Object GUID: %s\n", GUID_string(talloc_tos(), &object->type.type)); } - if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n"); + if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n"); printf("Object GUID: %s\n", GUID_string(talloc_tos(), &object->inherited_type.inherited_type)); } diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index a5e04a4a6c..3bf0b6f7a7 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -112,15 +112,15 @@ static void ads_disp_sec_ace_object(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct security_ace_object *object) { - if (object->flags & SEC_ACE_OBJECT_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_PRESENT\n"); + if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n"); printf("Object GUID: %s (%s)\n", GUID_string(mem_ctx, &object->type.type), ads_interprete_guid_from_object(ads, mem_ctx, &object->type.type)); } - if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n"); + if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n"); printf("Object GUID: %s (%s)\n", GUID_string(mem_ctx, &object->inherited_type.inherited_type), ads_interprete_guid_from_object(ads, mem_ctx, diff --git a/source3/libgpo/gpo_sec.c b/source3/libgpo/gpo_sec.c index 42ab72a99b..c72bb26732 100644 --- a/source3/libgpo/gpo_sec.c +++ b/source3/libgpo/gpo_sec.c @@ -38,12 +38,12 @@ static bool gpo_sd_check_agp_object_guid(const struct security_ace_object *objec } switch (object->flags) { - case SEC_ACE_OBJECT_PRESENT: + case SEC_ACE_OBJECT_TYPE_PRESENT: if (GUID_equal(&object->type.type, &ext_right_apg_guid)) { return True; } - case SEC_ACE_OBJECT_INHERITED_PRESENT: + case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: if (GUID_equal(&object->inherited_type.inherited_type, &ext_right_apg_guid)) { return True; diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c index 23c9610381..91d8591a05 100644 --- a/source3/rpc_parse/parse_sec.c +++ b/source3/rpc_parse/parse_sec.c @@ -73,11 +73,11 @@ static bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, if (!prs_uint32("obj_flags", ps, depth, &psa->object.object.flags)) return False; - if (psa->object.object.flags & SEC_ACE_OBJECT_PRESENT) + if (psa->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) if (!smb_io_uuid("obj_guid", &psa->object.object.type.type, ps,depth)) return False; - if (psa->object.object.flags & SEC_ACE_OBJECT_INHERITED_PRESENT) + if (psa->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) if (!smb_io_uuid("inh_guid", &psa->object.object.inherited_type.inherited_type, ps,depth)) return False; -- cgit From 4a35c974e97551b1ccbfa41d4c08f0598e3c26aa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 1 Mar 2009 11:39:44 +0100 Subject: Only copy sharename up from rap_to_pjobid Why?? :-) Another one of the little micro-optimizations that I just came across: If you allocate a variable in a sub-block like the "fstring sharename" in write_file(), gcc even with -O3 will allocate this variable unconditionally on the stack at the beginning of the routine. So with eliminating this fstring we cut 256 bytes of stack in a very hot code path writing to a file. It might make us a bit more cache-friendly. This would probably not be worth a second look if it involved larger code changes, but this one was just too simple to let it pass :-) --- source3/printing/printfsp.c | 3 +-- source3/printing/printing.c | 4 +++- source3/smbd/fileio.c | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index b485711f91..243b8ea03b 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -88,7 +88,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn, void print_fsp_end(files_struct *fsp, enum file_close_type close_type) { uint32 jobid; - fstring sharename; if (fsp->fh->private_options & FILE_DELETE_ON_CLOSE) { /* @@ -102,7 +101,7 @@ void print_fsp_end(files_struct *fsp, enum file_close_type close_type) string_free(&fsp->fsp_name); } - if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) { + if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) { DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n", (unsigned int)fsp->rap_print_jobid )); return; diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 49bd5ac8ba..fc3667ea3a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -117,7 +117,9 @@ bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) { struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr; - fstrcpy( sharename, jinfo->sharename ); + if (sharename != NULL) { + fstrcpy( sharename, jinfo->sharename ); + } *pjobid = jinfo->jobid; DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n", (unsigned int)*pjobid, (unsigned int)rap_jobid)); diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index a9a97a2d14..adf664b396 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -256,10 +256,9 @@ ssize_t write_file(struct smb_request *req, int write_path = -1; if (fsp->print_file) { - fstring sharename; uint32 jobid; - if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) { + if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) { DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n", (unsigned int)fsp->rap_print_jobid )); errno = EBADF; -- cgit From d776ac03c3ce8a9090b847f20d2cdd16d745441f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 1 Mar 2009 16:16:16 +0100 Subject: Move next_token_talloc() to top-level. --- lib/util/util.h | 15 +++++++ lib/util/util_str.c | 100 +++++++++++++++++++++++++++++++++++++++++++ source3/lib/util_str.c | 112 ------------------------------------------------- 3 files changed, 115 insertions(+), 112 deletions(-) diff --git a/lib/util/util.h b/lib/util/util.h index 27f94cd685..1f6e3b193b 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -204,6 +204,21 @@ _PUBLIC_ void display_set_stderr(void); /* The following definitions come from lib/util/util_str.c */ +bool next_token_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep); + +/** + * Get the next token from a string, return false if none found. Handles + * double-quotes. This version does not trim leading separator characters + * before looking for a token. + */ +bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep); + /** Trim the specified elements off the front and back of a string. diff --git a/lib/util/util_str.c b/lib/util/util_str.c index a2c50fd38f..8bf6026105 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -332,4 +332,104 @@ _PUBLIC_ void string_replace(char *s, char oldc, char newc) } } +/** + * @file + * @brief String utilities. + **/ + +static bool next_token_internal_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep, + bool ltrim) +{ + char *s; + char *saved_s; + char *pbuf; + bool quoted; + size_t len=1; + + *pp_buff = NULL; + if (!ptr) { + return(false); + } + + s = (char *)*ptr; + + /* default to simple separators */ + if (!sep) { + sep = " \t\n\r"; + } + + /* find the first non sep char, if left-trimming is requested */ + if (ltrim) { + while (*s && strchr_m(sep,*s)) { + s++; + } + } + + /* nothing left? */ + if (!*s) { + return false; + } + + /* When restarting we need to go from here. */ + saved_s = s; + + /* Work out the length needed. */ + for (quoted = false; *s && + (quoted || !strchr_m(sep,*s)); s++) { + if (*s == '\"') { + quoted = !quoted; + } else { + len++; + } + } + + /* We started with len = 1 so we have space for the nul. */ + *pp_buff = talloc_array(ctx, char, len); + if (!*pp_buff) { + return false; + } + + /* copy over the token */ + pbuf = *pp_buff; + s = saved_s; + for (quoted = false; *s && + (quoted || !strchr_m(sep,*s)); s++) { + if ( *s == '\"' ) { + quoted = !quoted; + } else { + *pbuf++ = *s; + } + } + + *ptr = (*s) ? s+1 : s; + *pbuf = 0; + + return true; +} + +bool next_token_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep) +{ + return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); +} + +/* + * Get the next token from a string, return false if none found. Handles + * double-quotes. This version does not trim leading separator characters + * before looking for a token. + */ + +bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep) +{ + return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); +} + diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 9358061797..b9ccb83e55 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -35,118 +35,6 @@ const char toupper_ascii_fast_table[128] = { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f }; -/** - * @file - * @brief String utilities. - **/ - -static bool next_token_internal_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep, - bool ltrim) -{ - char *s; - char *saved_s; - char *pbuf; - bool quoted; - size_t len=1; - - *pp_buff = NULL; - if (!ptr) { - return(false); - } - - s = (char *)*ptr; - - /* default to simple separators */ - if (!sep) { - sep = " \t\n\r"; - } - - /* find the first non sep char, if left-trimming is requested */ - if (ltrim) { - while (*s && strchr_m(sep,*s)) { - s++; - } - } - - /* nothing left? */ - if (!*s) { - return false; - } - - /* When restarting we need to go from here. */ - saved_s = s; - - /* Work out the length needed. */ - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if (*s == '\"') { - quoted = !quoted; - } else { - len++; - } - } - - /* We started with len = 1 so we have space for the nul. */ - *pp_buff = TALLOC_ARRAY(ctx, char, len); - if (!*pp_buff) { - return false; - } - - /* copy over the token */ - pbuf = *pp_buff; - s = saved_s; - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if ( *s == '\"' ) { - quoted = !quoted; - } else { - *pbuf++ = *s; - } - } - - *ptr = (*s) ? s+1 : s; - *pbuf = 0; - - return true; -} - -#if 0 -/* - * Get the next token from a string, return false if none found. Handles - * double-quotes. This version trims leading separator characters before - * looking for a token. - */ -bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize) -{ - return next_token_internal(ptr, buff, sep, bufsize, true); -} -#endif - -bool next_token_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); -} - -/* - * Get the next token from a string, return false if none found. Handles - * double-quotes. This version does not trim leading separator characters - * before looking for a token. - */ - -bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); -} - /** * Case insensitive string compararison. * -- cgit From 55903e6f9120f1ec58a8554813229975c3028a09 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 1 Mar 2009 16:19:38 +0100 Subject: Move next_token_talloc to util.c, as util_str.c is only compiled inside samba 4. --- lib/util/util.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/util/util_str.c | 100 ---------------------------------------------------- 2 files changed, 100 insertions(+), 100 deletions(-) diff --git a/lib/util/util.c b/lib/util/util.c index 988d8f9fa0..1f31f55e8b 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -836,4 +836,104 @@ _PUBLIC_ size_t utf16_len_n(const void *src, size_t n) return len; } +/** + * @file + * @brief String utilities. + **/ + +static bool next_token_internal_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep, + bool ltrim) +{ + char *s; + char *saved_s; + char *pbuf; + bool quoted; + size_t len=1; + + *pp_buff = NULL; + if (!ptr) { + return(false); + } + + s = (char *)*ptr; + + /* default to simple separators */ + if (!sep) { + sep = " \t\n\r"; + } + + /* find the first non sep char, if left-trimming is requested */ + if (ltrim) { + while (*s && strchr_m(sep,*s)) { + s++; + } + } + + /* nothing left? */ + if (!*s) { + return false; + } + + /* When restarting we need to go from here. */ + saved_s = s; + + /* Work out the length needed. */ + for (quoted = false; *s && + (quoted || !strchr_m(sep,*s)); s++) { + if (*s == '\"') { + quoted = !quoted; + } else { + len++; + } + } + + /* We started with len = 1 so we have space for the nul. */ + *pp_buff = talloc_array(ctx, char, len); + if (!*pp_buff) { + return false; + } + + /* copy over the token */ + pbuf = *pp_buff; + s = saved_s; + for (quoted = false; *s && + (quoted || !strchr_m(sep,*s)); s++) { + if ( *s == '\"' ) { + quoted = !quoted; + } else { + *pbuf++ = *s; + } + } + + *ptr = (*s) ? s+1 : s; + *pbuf = 0; + + return true; +} + +bool next_token_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep) +{ + return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); +} + +/* + * Get the next token from a string, return false if none found. Handles + * double-quotes. This version does not trim leading separator characters + * before looking for a token. + */ + +bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, + const char **ptr, + char **pp_buff, + const char *sep) +{ + return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); +} + diff --git a/lib/util/util_str.c b/lib/util/util_str.c index 8bf6026105..a2c50fd38f 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -332,104 +332,4 @@ _PUBLIC_ void string_replace(char *s, char oldc, char newc) } } -/** - * @file - * @brief String utilities. - **/ - -static bool next_token_internal_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep, - bool ltrim) -{ - char *s; - char *saved_s; - char *pbuf; - bool quoted; - size_t len=1; - - *pp_buff = NULL; - if (!ptr) { - return(false); - } - - s = (char *)*ptr; - - /* default to simple separators */ - if (!sep) { - sep = " \t\n\r"; - } - - /* find the first non sep char, if left-trimming is requested */ - if (ltrim) { - while (*s && strchr_m(sep,*s)) { - s++; - } - } - - /* nothing left? */ - if (!*s) { - return false; - } - - /* When restarting we need to go from here. */ - saved_s = s; - - /* Work out the length needed. */ - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if (*s == '\"') { - quoted = !quoted; - } else { - len++; - } - } - - /* We started with len = 1 so we have space for the nul. */ - *pp_buff = talloc_array(ctx, char, len); - if (!*pp_buff) { - return false; - } - - /* copy over the token */ - pbuf = *pp_buff; - s = saved_s; - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if ( *s == '\"' ) { - quoted = !quoted; - } else { - *pbuf++ = *s; - } - } - - *ptr = (*s) ? s+1 : s; - *pbuf = 0; - - return true; -} - -bool next_token_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); -} - -/* - * Get the next token from a string, return false if none found. Handles - * double-quotes. This version does not trim leading separator characters - * before looking for a token. - */ - -bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); -} - -- cgit